Search code examples
javascriptjqueryjquery-uidraggablejquery-ui-draggable

JQuery-UI Draggable drag at mouse position


I have this code:

<!doctype html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>jQuery UI Draggable - Default functionality</title>
    <style>
        #draggable {
            width: 150px;
            height: 150px;
            padding: 0.5em;
            border: 1px solid red;
        }

        .container {
            height: 500px;
            width: 500px;
            border: 1px solid green;
            transform: scale(1.6);
            position: relative;
            left: 300px;
            top: 150px;
        }
    </style>
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script>
        $(function() {
            $("#draggable").draggable();
        });
    </script>
</head>

<body>
    <div class="container">
        <div id="draggable" class="ui-widget-content">
            <p>Drag me around</p>
        </div>
    </div>




</body>

</html>

It works perfect without transform: scale(1.6);. However, the #draggable moves faster than the mouse with the transform property. How can I make it draggable and scale the container to a value like 1.65? Is there any draggable option I'm supposed to use?


Solution

  • This can be solved by adjusting for the transform: scale(1.6). When the item is dragged, it uses it's position to adjust the top and left of the dragged item. With the scale(), these values are off and you will see the items movement move that same factor faster then the mouse.

    x1 = x * 1.6; y1 = y * 1.6;

    To move with the mouse, we need to adjust this back to the same 1:1 (instead of 1:1.6) ratio. This can be done like so:

    jQuery > Draggable > Drag Option

    drag: function(e, ui) {
      // Adjust for Scale
      var myScale = parseFloat($('.container').css('transform').split(',')[3]);
      var myTop = Math.round(ui.position.top / myScale);
      var myLeft = Math.round(ui.position.left / myScale);
      ui.position = {
        top: myTop,
        left: myLeft
      };
    }
    

    FYI, $('.container').css('transform') will return: matrix(1.6, 0, 0, 1.6, 0, 0). See more: Get CSS transform property with jQuery

    You could hard code 1.6 into your script, but I like to keep things portable. So if you change the CSS, you don't have to change this script. See more about setting position: http://api.jqueryui.com/draggable/#event-drag

    Working Example: https://jsfiddle.net/Twisty/1gnehyum/