jQuery Drag/Resize with CSS Transform Scale

前端 未结 13 1883
忘了有多久
忘了有多久 2020-11-27 13:39

I am applying a CSS transform (and the browser specific -webkit, -o etc):

transform: matrix(0.5 , 0 , 0, 0.5, 0 , 0);

to a div then using jQuery\'s draggable

相关标签:
13条回答
  • 2020-11-27 14:15

    I was trying the transform scale() fix for resizable posted by gungfoo on a element displayed at 10% of its actual size and the method didin't work. The cursor still moved away from the element during resizing.

    I changed the last two lines of the resizeFix method to directly update the element's width and height and this solved my issue.

    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);
    }
    
    0 讨论(0)
  • 2020-11-27 14:17

    None of these solutions worked for me, as for one, I could not transform the parent of the draggables - only the draggables themselves were transformed.

    This is how I fixed this issue:

    $('.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);
        }
    });
    

    Zoom is by default 0.

    To scale the draggables I did the following:

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

    And everything seems to work allright.

    0 讨论(0)
  • 2020-11-27 14:19

    My own "answer" was on this occasion was to adapt jQuery UI draggable to make a separate interaction, called "traggable".

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

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

    Would still like to hear about any alternatives...

    0 讨论(0)
  • 2020-11-27 14:21

    For a long time I wonder why @GungFoo solution not working for me for Jquery Resizable but some people told it was worked. Finally I found out there are 4 points for using jQuery Draggable and Resizable with CSS Transform Scale:

    1. Using @GungFoo solutions!
    2. Using separate divs for draggable and resizable!
    3. Using proper CSS Transform Origin for divs!
    4. Using proper CSS Direction for divs!

    Check some of this problems:

    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>

    Thanks to @Guy ;)

    0 讨论(0)
  • 2020-11-27 14:23

    Here is my solution. Some of the code posted above did not work for me.

    I have a dragable image and I apply CSS transform rotate and scale onto that image. Once I scale/rotate it the position is off at drag-start. To fix it I calculate the setpoint difference from stop to start and on-drag apply a new setpoint with the difference factored in.

    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));
      }
    });
    

    The CSS transform-origin trick does fixes the bug for scale only. Rotation should be around center so you want to keep the default 50% 50%.

    0 讨论(0)
  • 2020-11-27 14:23

    For different resize corner

    $('.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 讨论(0)
提交回复
热议问题