Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery draggable and -webkit-transform: scale();

I have a situation where inside a div there are draggable items. However, when the parent div is scaled using -webkit-transform, the draggable obviously stops working properly.

I've reproduced the scenario here.

As you can see, the draggable item moves relative to the document, even though the parent is in an entirely different scale.

I have the scale (1.5 in the example) as a variable in JS, so I can use that, but where? I'd need to divide the dragging distance by the scale, right? Where could I do this?

Edit: I've tried setting a function to drag-event, but haven't been able to figure out how to actually alter the dragging distance.

Edit2: I digged the jQuery UI source, and it seems that there's no way to do this from the event drag:

if(this._trigger('drag', event, ui) === false) {
    this._mouseUp({});
    return false;
}

As you can see, the return value of the callback-function isn't stored in any way. The position of the element is changed after the callback has fired, so changing the CSS inside the callback doesn't work.

You can see the relevant code here by using in-browser search with this string:

_mouseDrag: function(event, noPropagation) {
like image 524
Martti Laine Avatar asked Dec 14 '12 15:12

Martti Laine


1 Answers

Due to my small amount of experience with JavaScript I didn't realise that the callback could in fact modify the position, even though it doesn't return anything. This is because in JS apparently parameters are by default passed by reference.

Here's a working code:

// Couldn't figure out a way to use the coordinates
// that jQuery also stores, so let's record our own.
var click = {
    x: 0,
    y: 0
};

$('.draggable').draggable({

    start: function(event) {
        click.x = event.clientX;
        click.y = event.clientY;
    },

    drag: function(event, ui) {

        // This is the parameter for scale()
        var zoom = 1.5;

        var original = ui.originalPosition;

        // jQuery will simply use the same object we alter here
        ui.position = {
            left: (event.clientX - click.x + original.left) / zoom,
            top:  (event.clientY - click.y + original.top ) / zoom
        };

    }

});
like image 186
Martti Laine Avatar answered Oct 23 '22 12:10

Martti Laine