web-dev-qa-db-fra.com

jQuery glisser/redimensionner avec l'échelle de transformation CSS

J'applique une transformation CSS (et le navigateur spécifique -webkit, -o, etc.):

transformée: matrice (0,5, 0, 0, 0,5, 0, 0);

à une div en utilisant les plugins draggable () et resizable () de jQuery sur les enfants de cette div.

Le problème que j’avais, c’est que lors du glissement ou du redimensionnement des éléments enfants, les modifications apportées par jQuery n’étaient pas "synchronisées" avec la souris par un facteur égal à l’échelle appliquée.

J'ai trouvé une solution sur stackoverflow (bien que, bêtement, je ne l'ai pas signet et maintenant je ne le trouve pas ...) qui proposait de corriger les plugins, et cela fonctionnait à merveille. Il a suivi cette ligne:

function monkeyPatch_mouseStart() {
  // don't really need this, but in case I did, I could store it and chain
  // var oldFn = $.ui.draggable.prototype._mouseStart ;
  $.ui.draggable.prototype._mouseStart = function(event) {

    var o = this.options;

    //Create and append the visible helper
    this.helper = this._createHelper(event);

    //Cache the helper size
    this._cacheHelperProportions();

    //If ddmanager is used for droppables, set the global draggable
    if($.ui.ddmanager)
      $.ui.ddmanager.current = this;

    /*
     * - Position generation -
     * This block generates everything position related - it's the core of draggables.
     */

    //Cache the margins of the original element
    this._cacheMargins();

    //Store the helper's css position
    this.cssPosition = this.helper.css("position");
    this.scrollParent = this.helper.scrollParent();

    //The element's absolute position on the page minus margins

    //PATCH CODE
    this.offset = this.positionAbs = getViewOffset(this.element[0]);
    //END

    this.offset = {
      top: this.offset.top - this.margins.top,
      left: this.offset.left - this.margins.left
    };

    $.extend(this.offset, {
      click: { //Where the click happened, relative to the element
        left: event.pageX - this.offset.left,
        top: event.pageY - this.offset.top
      },
      parent: this._getParentOffset(),
      relative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper
    });

    //Generate the original position
    this.originalPosition = this.position = this._generatePosition(event);
    this.originalPageX = event.pageX;
    this.originalPageY = event.pageY;

    //Adjust the mouse offset relative to the helper if 'cursorAt' is supplied
    if(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt)){
    }

    //Set a containment if given in the options
    if(o.containment)
      this._setContainment();

    //Trigger event + callbacks
    if(this._trigger("start", event) === false) {
      this._clear();
      return false;
    }

    //Recache the helper size
    this._cacheHelperProportions();

    //Prepare the droppable offsets
    if ($.ui.ddmanager && !o.dropBehaviour)
      $.ui.ddmanager.prepareOffsets(this, event);

    this.helper.addClass("ui-draggable-dragging");
    this._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position

    //If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)
    if ( $.ui.ddmanager && $.ui.ddmanager.dragStart) $.ui.ddmanager.dragStart(this, event);

    return true;
  }
 }

function getViewOffset(node) {
  var x = 0, y = 0, win = node.ownerDocument.defaultView || window;
  if (node) addOffset(node);
  return { left: x, top: y };

  function getStyle(node) {
    return node.currentStyle || // IE
           win.getComputedStyle(node, '');
  }

  function addOffset(node) {
    var p = node.offsetParent, style, X, Y;
    x += parseInt(node.offsetLeft, 10) || 0;
    y += parseInt(node.offsetTop, 10) || 0;

    if (p) {
      x -= parseInt(p.scrollLeft, 10) || 0;
      y -= parseInt(p.scrollTop, 10) || 0;

      if (p.nodeType == 1) {
        var parentStyle = getStyle(p)
          , localName   = p.localName
          , parent      = node.parentNode;
        if (parentStyle.position != 'static') {
          x += parseInt(parentStyle.borderLeftWidth, 10) || 0;
          y += parseInt(parentStyle.borderTopWidth, 10) || 0;

          if (localName == 'TABLE') {
            x += parseInt(parentStyle.paddingLeft, 10) || 0;
            y += parseInt(parentStyle.paddingTop, 10) || 0;
          }
          else if (localName == 'BODY') {
            style = getStyle(node);
            x += parseInt(style.marginLeft, 10) || 0;
            y += parseInt(style.marginTop, 10) || 0;
          }
        }
        else if (localName == 'BODY') {
          x += parseInt(parentStyle.borderLeftWidth, 10) || 0;
          y += parseInt(parentStyle.borderTopWidth, 10) || 0;
        }

        while (p != parent) {
          x -= parseInt(parent.scrollLeft, 10) || 0;
          y -= parseInt(parent.scrollTop, 10) || 0;
          parent = parent.parentNode;
        }
        addOffset(p);
      }
    }
    else {
      if (node.localName == 'BODY') {
        style = getStyle(node);
        x += parseInt(style.borderLeftWidth, 10) || 0;
        y += parseInt(style.borderTopWidth, 10) || 0;

        var htmlStyle = getStyle(node.parentNode);
        x -= parseInt(htmlStyle.paddingLeft, 10) || 0;
        y -= parseInt(htmlStyle.paddingTop, 10) || 0;
      }

      if ((X = node.scrollLeft)) x += parseInt(X, 10) || 0;
      if ((Y = node.scrollTop))  y += parseInt(Y, 10) || 0;
    }
  }
}
var isNumber = function(value) {
  return !isNaN(parseInt(value, 10));
};

J'ai apporté mes propres modifications telles que (vous pouvez voir sur les lignes 6-7 la multiplication du mouvement par un "facteur d'échelle"):

 $.ui.draggable.prototype._generatePosition = function(event) {
    var o = this.options, scroll = this.cssPosition == 'absolute' && !(this.scrollParent[0] != document && $.ui.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);
    var pageX = event.pageX;
    var pageY = event.pageY;
    //PATCH CODE
    if($(this.element[0]).hasClass('item')){
        pageY = this.originalPageY + ((pageY - this.originalPageY)*(1/$.viewbox.foreground.scale));
        pageX = this.originalPageX + ((pageX - this.originalPageX)*(1/$.viewbox.foreground.scale));
    }
    //END
    /*
     * - Position constraining -
     * Constrain the position to a mix of grid, containment.
     */

    if(this.originalPosition) { //If we are not dragging yet, we won't check for options

      if(this.containment) {
        if(event.pageX - this.offset.click.left < this.containment[0]) pageX = this.containment[0] + this.offset.click.left;
        if(event.pageY - this.offset.click.top < this.containment[1]) pageY = this.containment[1] + this.offset.click.top;
        if(event.pageX - this.offset.click.left > this.containment[2]) pageX = this.containment[2] + this.offset.click.left;
        if(event.pageY - this.offset.click.top > this.containment[3]) pageY = this.containment[3] + this.offset.click.top;
      }

      if(o.grid) {
        var top = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];
        pageY = this.containment ? (!(top - this.offset.click.top < this.containment[1] || top - this.offset.click.top > this.containment[3]) ? top : (!(top - this.offset.click.top < this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;

        var left = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];
        pageX = this.containment ? (!(left - this.offset.click.left < this.containment[0] || left - this.offset.click.left > this.containment[2]) ? left : (!(left - this.offset.click.left < this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;
      }
    }
    return {
      top: (
        pageY                               // The absolute mouse position
        - this.offset.click.top                         // Click offset (relative to the element)
        - this.offset.relative.top                        // Only for relative positioned nodes: Relative offset from element to offset parent
        - this.offset.parent.top                        // The offsetParent's offset without borders (offset + border)
        + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))
      ),
      left: (
        pageX                               // The absolute mouse position
        - this.offset.click.left                        // Click offset (relative to the element)
        - this.offset.relative.left                       // Only for relative positioned nodes: Relative offset from element to offset parent
        - this.offset.parent.left                       // The offsetParent's offset without borders (offset + border)
        + ($.browser.safari && $.browser.version < 526 && this.cssPosition == 'fixed' ? 0 : ( this.cssPosition == 'fixed' ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))
      )
    };

  }

Merci donc à celui qui a suggéré cela.

Alors, ma question! Quelqu'un a-t-il déjà trouvé un moyen intéressant d'avoir des événements déplaçables/redimensionnables dans un élément mis à l'échelle qui ne nécessite pas de correctif pour jQuery? J'ai googlé, et c'était la meilleure solution que j'ai pu trouver. Est-ce que quelqu'un sait d'alternative à jQuery qui fonctionne peut-être dans ces conditions, avec des transformations CSS?

Merci beaucoup pour toutes les réponses.

45
paullth

Cela fait longtemps que cette question a été posée. J'ai trouvé (créé) une réponse. Tout ce qu'il faut, c'est configurer des gestionnaires de rappel. Pas besoin de retouche jquery-ui! 

Remarque: zoomScale dans cet exemple est une variable globale et la transformation est définie en utilisant animate (avec l'aide de jquery.transform.js ) comme suit:

target.animate({
    transform: 'scale(' + zoomScale + ')'
});

Regarde ça:

transform scale () correctif pour redimensionnable:

$(this).resizable({
    minWidth: -(contentElem.width()) * 10,  // these need to be large and negative
    minHeight: -(contentElem.height()) * 10, // so we can shrink our resizable while scaled
    resize: function(event, ui) {

        var changeWidth = ui.size.width - ui.originalSize.width; // find change in width
        var newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale

        var changeHeight = ui.size.height - ui.originalSize.height; // find change in height
        var newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale

        ui.size.width = newWidth;
        ui.size.height = newHeight;

    }
});

transform scale () correctif pour glissable:

$(this).draggable({
    handle: '.drag-handle',
    start: function(event, ui) {
        ui.position.left = 0;
        ui.position.top = 0;
    },
    drag: function(event, ui) {

        var changeLeft = ui.position.left - ui.originalPosition.left; // find change in left
        var newLeft = ui.originalPosition.left + changeLeft / (( zoomScale)); // adjust new left by our zoomScale

        var changeTop = ui.position.top - ui.originalPosition.top; // find change in top
        var newTop = ui.originalPosition.top + changeTop / zoomScale; // adjust new top by our zoomScale

        ui.position.left = newLeft;
        ui.position.top = newTop;

    }
});

Faites-moi savoir si vous trouvez des problèmes ou des améliorations à ce sujet. :)

Référence: jQuery-UI redimensionnable/déplaçable avec transform: scale () set

36
Gung Foo

Ma propre "réponse" était à cette occasion d'adapter l'interface utilisateur glissable de jQuery pour créer une interaction séparée, appelée "traggable". 

https://github.com/paullth/JS-libs

http://jsfiddle.net/paul_herve/ws27C/4/

J'aimerais encore entendre parler de toute alternative ...

3
paullth

Une autre approche consiste à ajouter un plugin qui compense la transformation (n'oubliez pas d'ajouter "transform: true" à l'initialisation du plugin. 

Le fichier ui.draggable doit être transmis via une matrice inverse de la transformation afin de positionner l'élément dans l'espace non transformé que le navigateur transforme ensuite à l'affichage.

Pour "draggable", les éléments suivants ont fonctionné pour moi (jqueryui 1.10) (le calcul de matrice que j’ai tiré de jquery.panzoom):

var Matrix = function(a, b, c, d, e, f, g, h, i) {
    if ($.type(a) === 'array') {
        this.elements = [
            +a[0], +a[2], +a[4],
            +a[1], +a[3], +a[5],
                0,     0,     1
        ];
    } else {
        this.elements = [
            a, b, c,
            d, e, f,
            g || 0, h || 0, i || 1
        ];
    }
};

Matrix.prototype = {
    /**
     * Multiply a 3x3 matrix by a similar matrix or a vector
     * @param {Matrix|Vector} matrix
     * @return {Matrix|Vector} Returns a vector if multiplying by a vector
     */
    x: function(matrix) {
        var isVector = matrix instanceof Vector;

        var a = this.elements,
            b = matrix.elements;

        if (isVector && b.length === 3) {
            // b is actually a vector
            return new Vector(
                a[0] * b[0] + a[1] * b[1] + a[2] * b[2],
                a[3] * b[0] + a[4] * b[1] + a[5] * b[2],
                a[6] * b[0] + a[7] * b[1] + a[8] * b[2]
            );
        } else if (b.length === a.length) {
            // b is a 3x3 matrix
            return new Matrix(
                a[0] * b[0] + a[1] * b[3] + a[2] * b[6],
                a[0] * b[1] + a[1] * b[4] + a[2] * b[7],
                a[0] * b[2] + a[1] * b[5] + a[2] * b[8],

                a[3] * b[0] + a[4] * b[3] + a[5] * b[6],
                a[3] * b[1] + a[4] * b[4] + a[5] * b[7],
                a[3] * b[2] + a[4] * b[5] + a[5] * b[8],

                a[6] * b[0] + a[7] * b[3] + a[8] * b[6],
                a[6] * b[1] + a[7] * b[4] + a[8] * b[7],
                a[6] * b[2] + a[7] * b[5] + a[8] * b[8]
            );
        }
        return false; // fail
    },
    /**
     * Generates an inverse of the current matrix
     * @returns {Matrix}
     */
    inverse: function() {
        var d = 1 / this.determinant(),
            a = this.elements;
        return new Matrix(
            d * ( a[8] * a[4] - a[7] * a[5]),
            d * (-(a[8] * a[1] - a[7] * a[2])),
            d * ( a[5] * a[1] - a[4] * a[2]),

            d * (-(a[8] * a[3] - a[6] * a[5])),
            d * ( a[8] * a[0] - a[6] * a[2]),
            d * (-(a[5] * a[0] - a[3] * a[2])),

            d * ( a[7] * a[3] - a[6] * a[4]),
            d * (-(a[7] * a[0] - a[6] * a[1])),
            d * ( a[4] * a[0] - a[3] * a[1])
        );
    },
    /**
     * Calculates the determinant of the current matrix
     * @returns {Number}
     */
    determinant: function() {
        var a = this.elements;
        return a[0] * (a[8] * a[4] - a[7] * a[5]) - a[3] * (a[8] * a[1] - a[7] * a[2]) + a[6] * (a[5] * a[1] - a[4] * a[2]);
    }
};

var Vector = function (x, y, z) {
    this.elements = [ x, y, z ];
};

/**
 * Get the element at zero-indexed index i
 * @param {Number} i
 */
Vector.prototype.e = Matrix.prototype.e = function(i) {

    if( this.elements[ i ] != undefined ){
        return this.elements[ i ];    
    }

    return this.elements;
};    

$.ui.plugin.add("draggable", "transform", {

    start: function( event, ui ) {

        if(!$(this).data('ui-draggable')){
            return false;
        }            

        var inst = $(this).data("ui-draggable");

        inst.matrix = new Matrix(function(matrix){

            var rmatrix = new RegExp(
                    '^matrix\\(' +
                    '(\\-?[\\d\\.e]+)' + '\\,?\\s*' +
                    '(\\-?[\\d\\.e]+)' + '\\,?\\s*' +
                    '(\\-?[\\d\\.e]+)' + '\\,?\\s*' +
                    '(\\-?[\\d\\.e]+)' + '\\,?\\s*' +
                    '(\\-?[\\d\\.e]+)' + '\\,?\\s*' +
                    '(\\-?[\\d\\.e]+)' + '\\)$'
            );                

            var matrix = rmatrix.exec( matrix );
            if (matrix) {
                matrix.shift();
            }
            return matrix || [ 1, 0, 0, 1, 0, 0 ];

        }([$(this).parents('[style*="transform"]').css('transform')]));            
    },
    drag: function( event, ui ) {

        if(!$(this).data('ui-draggable')){
            return false;
        }            

        var inst = $(this).data("ui-draggable");

        var t_pos = inst.matrix.inverse().x(new Vector(ui.position.left, ui.position.top, 0));

        ui.position.left = t_pos.e(0);
        ui.position.top = t_pos.e(1);                   

        if(inst.options.grid) {
            ui.position.left = ui.position.left - ui.position.left % inst.options.grid[0];
            ui.position.top  = ui.position.top - ui.position.top % inst.options.grid[1];                
        }

        if( inst.containment ){

            if( ui.position.left < inst.containment[0] ){
                ui.position.left = inst.containment[0];
            }

            if( ui.position.left > inst.containment[2] ){
                ui.position.left = inst.containment[2];
            }                

            if( ui.position.top < inst.containment[1] ){
                ui.position.top = inst.containment[1];
            }  

            if( ui.position.top > inst.containment[3] ){
                ui.position.top = inst.containment[3];
            }
        }
    },     
});
2
gal

La meilleure réponse a été de travailler pour moi jusqu'à ce que j'ai trouvé un glitch sur draggable :(

Lorsque le confinement lui-même est également mis à l'échelle:

  • il ne peut pas être complètement déplacé dans sa boîte de confinement si mis à l'échelle <1
  • il peut être glissé en dehors de la boîte de confinement s'il est mis à l'échelle> 1

Heureusement, j'ai trouvé une solution ici

2
elegisandi

J'essayais le correctif transform scale () pour redimensionnable posté par gungfoo sur un élément affiché à 10% de sa taille réelle et la méthode ne fonctionnait pas. Le curseur s'est toujours éloigné de l'élément pendant le redimensionnement.

J'ai changé les deux dernières lignes de la méthode resizeFix pour mettre à jour directement la largeur et la hauteur de l'élément, ce qui a résolu mon problème.

function resizeFix(event, ui) {

    var changeWidth = ui.size.width - ui.originalSize.width; // find change in width
    var newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale

    var changeHeight = ui.size.height - ui.originalSize.height; // find change in height
    var newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale

    ui.originalElement.width(newWidth);
    ui.originalElement.height(newHeight);
}
1
Malcolm Wax

j'ai eu un problème similaire avec la transformation et j'ai fini par le résoudre avec CSS:

transform-Origin

http://www.w3schools.com/cssref/css3_pr_transform-Origin.asp

l'avez-vous essayé? Peut-être que cela vous aidera.

1
Guy

J'ai découvert que je pouvais simplement envelopper l'élément redimensionné avec un autre div et le placer de manière glissable dessus.

1
galatians

Pendant longtemps, je me suis demandé pourquoi la solution @GungFoo ne fonctionnait pas pour Jquery Resizable, mais certaines personnes ont dit qu'elle fonctionnait. Enfin, j'ai découvert 4 points d'utilisation de jQuery pouvant être déplacés par glissement et redimensionnables avec l'échelle de transformation CSS:

  1. Utilisation des solutions @GungFoo!
  2. Utilisation de divs séparés pour draggable et redimensionnable!
  3. Utiliser le bon CSS Transform Origin pour les divs!
  4. Utiliser les instructions CSS appropriées pour les divs!

Vérifiez certains de ces problèmes:

function resizeDiv(event, ui) {
        debugger;
        var changeWidth = ui.size.width - ui.originalSize.width; 
        var newWidth = ui.originalSize.width + changeWidth / 4; 

        var changeHeight = ui.size.height - ui.originalSize.height;
        var newHeight = ui.originalSize.height + changeHeight / 4; 

        ui.size.width = newWidth;
        ui.size.height = newHeight;

};
$('#box').resizable({
    minWidth: -($(this).width()) * 10,
    minHeight: -($(this).height()) * 10, 
    resize: resizeDiv
});

$('#box2').resizable({
    minWidth: -($(this).width()) * 10,
    minHeight: -($(this).height()) * 10, 
    resize: resizeDiv
});

$('#box3').resizable({
    minWidth: -($(this).width()) * 10,
    minHeight: -($(this).height()) * 10, 
    resize: resizeDiv
});

$('#box4').resizable({
    minWidth: -($(this).width()) * 10,
    minHeight: -($(this).height()) * 10, 
    resize: resizeDiv
});
.box{
  position:absolute;
  width:30px;
  height:30px;
  border:1px solid black;
  font-size:3pt;
  overflow:hidden;
  -webkit-transform:scale(4);
  direction:ltr;
}
#box{
  transform-Origin: top left;
  top: 0;
  left:0;
}
#box2{
  transform-Origin: bottom left;
  top: 250px;
  left:0;
}
#box3{
  direction:rtl;
  left: 250px;
  top: -10px;
}
<link href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/themes/smoothness/jquery-ui.css" rel="stylesheet" type="text/css" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
     
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.2/jquery-ui.min.js"></script>

<div id= 'box' class="box"> 
True styles
</div>

<div id= 'box2' class="box"> 
Bad transform-orgin
</div>

<div id= 'box3' class="box"> 
Bad direction
</div>

Merci à @Guy;)

1
Naser Yousefi

Voici ma solution. Certains des codes postés ci-dessus ne fonctionnaient pas pour moi.

J'ai une image déplaçable et j'applique la transformation CSS, la rotation et la mise à l'échelle sur cette image. Une fois que je l'ai mis à l'échelle/pivoté, la position est désactivée au début du glissement. Pour résoudre ce problème, je calcule la différence entre les points de consigne d’arrêt pour commencer et, en faisant glisser, applique un nouveau point de consigne avec la différence prise en compte.

var $img = $("#my-image-id");

$img.posLeft  = 0;
$img.posTop  = 0;
$img.diffLeft  = 0;
$img.diffTop  = 0;

$img.draggable({
  start: function( event, ui ) {
    //check the difference from start to stop setpoints
    $img.diffLeft  = $img.posLeft-ui.position.left;
    $img.diffTop  = $img.posTop-ui.position.top;
    //console.log('start x: '+Math.floor(ui.position.left)+' y: '+Math.floor(ui.position.top));
    //console.log('diff x: '+Math.floor($img.posLeft-ui.position.left)+' y: '+Math.floor($img.posTop-ui.position.top));
  },
  drag: function( event, ui ) {
    //fix the offset bug that is applied after CSS transform, to do that just add the value difference
    ui.position.left = ui.position.left+$img.diffLeft;
    ui.position.top = ui.position.top+$img.diffTop;
    //console.log('drag x: '+ui.position.left+' y: '+ui.position.top);
  },
  stop: function( event, ui ) {
    //save the last applied setpoints
    $img.posLeft = ui.position.left;
    $img.posTop = ui.position.top;
    //console.log('stop x: '+Math.floor(ui.position.left)+' y: '+Math.floor(ui.position.top));
  }
});

L'astuce de transformation-origine de CSS corrige le bogue uniquement pour l'échelle. La rotation doit être autour du centre afin que vous souhaitiez conserver la valeur par défaut de 50% 50%.

0
user2862304

Aucune de ces solutions ne fonctionnait pour moi, car je ne pouvais pas transformer le parent des objets glissables - seuls les objets glissables eux-mêmes étaient transformés.

Voici comment j'ai résolu ce problème:

$('.draggable').draggable(
{
    cancel: '.restrict-drag',
    scroll: false,
    containment: '#contain',

    start: function(event, ui) 
    {
        ui.position.left = 0;
        ui.position.top = 0;
    },

    drag: function(event, ui) 
    {
        ui.position.left = ui.position.left - ($(event.target).width() * Zoom);
        ui.position.top = ui.position.top - ($(event.target).height() * Zoom);
    }
});

Le zoom est par défaut à 0.

Pour redimensionner les objets glissables, j'ai procédé comme suit:

function changeZoom(zoom)
{
    $('.draggable').each(function() { $(this).css('transform-Origin', '50% 50%'); $(this).css('transform', 'scale(' + zoom + ')'); });
    Zoom = zoom; // Global Zoom-variable
}

Et tout semble bien marcher.

0
Piwwoli

J'ai eu le même problème, et le moyen le plus simple pour moi était de NE PAS utiliser la fonctionnalité déplaçable de jquery-ui car elle ne supportait pas les propriétés de transformation CSS3.

Ce qui a vraiment bien marché pour moi, c’est d’implémenter une propre fonctionnalité glissable: http://css-tricks.com/snippets/jquery/draggable-without-jquery-ui/

Je sais que cela ne résout pas votre problème à 100%, car vous souhaitez toujours utiliser la fonctionnalité déplaçable de jquery-ui, mais cela pourrait aider les autres.

0
eav

J'ajouterais ceci comme commentaire à la réponse acceptée par Gung Foo mais je n'ai pas le représentant à commenter.

J'ai trouvé que la réponse de Gung fonctionnait parfaitement pour moi, mais le correctif redimensionnable ne fonctionnait que lorsque vous le glissiez du coin inférieur droit. J'ai également des poignées sur les trois autres coins et j'ai constaté que l'élément se déplaçait. Je devais donc ajouter le correctif de déplaçable aux fonctions redimensionnables. 

Peut-être y a-t-il une meilleure façon, ou quelque chose m'a échappé, mais j'ai trouvé la modification de la taille ci-dessous adaptée à tous les besoins:

$(this).resizable({
    minWidth: -(contentElem.width()) * 10,  // these need to be large and negative
    minHeight: -(contentElem.height()) * 10, // so we can shrink our resizable while scaled

    // adjust the initial position to accomodate for the scale
    start: function(event, ui){
        ui.position.left = Math.round(ui.position.left/zoomScale);
        ui.position.top = Math.round(ui.position.top/zoomScale);
        ui.originalPosition.left = ui.position.left;
        ui.originalPosition.top = ui.position.top;
    },

    resize: function(event, ui) {

        var changeWidth = ui.size.width - ui.originalSize.width; // find change in width
        var newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale

        var changeHeight = ui.size.height - ui.originalSize.height; // find change in height
        var newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale

        ui.size.width = newWidth;
        ui.size.height = newHeight;

        // if the position is changed by a NW,NE,SW handle resize adjust for the scale
        var changeWidth = ui.size.width - ui.originalSize.width; // find change in width
        var newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale

        var changeHeight = ui.size.height - ui.originalSize.height; // find change in height
        var newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale

        ui.size.width = newWidth;
        ui.size.height = newHeight;

    }
});
0
kk64738

Pour différents coins de redimensionnement

$('.rect-item').resizable({
        handles: 'n,e,s,w,ne,se,sw,nw',
        resize: (e, ui) => {
          const zoomScale = Your scale;
          const changeWidth = ui.size.width - ui.originalSize.width; // find change in width
          const newWidth = ui.originalSize.width + changeWidth / zoomScale; // adjust new width by our zoomScale

          const changeHeight = ui.size.height - ui.originalSize.height; // find change in height
          const newHeight = ui.originalSize.height + changeHeight / zoomScale; // adjust new height by our zoomScale

          ui.size.width = newWidth;
          ui.size.height = newHeight;

          // here
          const posOrigin = ui.originalPosition;
          if (posOrigin.left !== ui.position.left) {
            ui.position.left = posOrigin.left - changeWidth / zoomScale;
          }
          if (posOrigin.top !== ui.position.top) {
            ui.position.top = posOrigin.top - changeHeight / zoomScale;
          }

        }
      });
0
xjinjin