1

Has anyone used panzoom with jquery draggable snap feature? I need to scale the parent div (#canvas) and allow child elements (.draggable) to be dragged and snapped to each other. All of this works very well except when scaled. If scaled/zoomed the positioning of snapped elements would be off a few pixels.

I tried css zoom, css transform(scale) but both cause an issue. I originally had a common cursor positioning issue others seems to have on scale but was able to fix that. If someone has come across this issue or has an idea I appreciate the help....or an entirely different approach is always welcome.

Here is a Codepen sample that shows the issue if you drag the green tiles around: https://codepen.io/5kyt3k/pen/Poomead

var menuWidth = 70; //Nav bar width (set in css file)
var canvasWidth = 1900; //#Canvas width (set in css file)
var currentZoom = ((window.innerWidth - menuWidth)/canvasWidth);
var currentScale = 1;

//Auto zoom #canvas to window size on load
$(document).ready(function () {
  $('#canvas').panzoom({
    disablePan: true,
    startTransform: 'scale('+ currentZoom +')',
    increment: 0.1,
    $zoomIn: $("#zoom-in"),
    $zoomOut: $("#zoom-out"),
  });

  $('#reset').click(function () {
    $('#canvas').panzoom("zoom", currentScale); //Not Working
  });
});

function dragTiles(){
  $( ".draggable" ).draggable({
    zIndex: 100,
    snap: ".driver",
    snapTolerance: 20,

    revert : function(droppableContainer){
      if(droppableContainer) {
        //alert('valid');
      }else {
        //alert('invalid');
      }
      return(droppableContainer)
    },
    //containment: '#canvas',
    start: function(e){
      $(this).removeClass('prevent');
      var pz = $("#canvas");
      //we need current scale factor to adjust coordinates of dragging element
      currentScale = pz.panzoom("getMatrix")[0];
      $(this).css("cursor","move");
      pz.panzoom("disable");//disable panzoom to avoid double offset
    },
    drag:function(e,ui){
      //fix scale issue
      ui.position.left = ui.position.left/currentScale;
      ui.position.top = ui.position.top/currentScale;
    },
    stop: function(e,ui){
      $(this).addClass('prevent');
      $(this).css("cursor","");
      //enable panzoom back
      $("#canvas").panzoom("enable");
    }
  })
   $(".tile-content").droppable({
     accept: '.draggable',
   });
};

$( ".add" ).click(function() {
  var item = $('#name').val();
  var dsc = $('#dsc').val();
  var type = $('#type').val().toLowerCase().replace(/ /g,'-');
  if(item !== null && item !== ''){
    $('#canvas').append('<div class="draggable '+ type +' prevent" name="'+ item +'" type="'+ type +'"><div class="tile-content">' + item + '<span class="dsc">' + dsc + '</span></div></div>');
    dragTiles();
    removeTile();
  } else{
    console.log('empty');
  }
});
5kyt3k
  • 11
  • 2
  • are the position values being converted to percentages? – Souleste Oct 24 '19 at 19:46
  • no they are not – 5kyt3k Oct 24 '19 at 22:06
  • They probably should be. left, top, height, width – Souleste Oct 24 '19 at 22:11
  • I added a codepen sample as well – 5kyt3k Oct 24 '19 at 23:53
  • No luck with percentages – 5kyt3k Oct 25 '19 at 01:54
  • I changed canvas width in the css to `100%` and `var canvasWidth` to `var canvasWidth = $('#canvas').width()` and the draggable widgets seem to be snapping more accurately. – Souleste Oct 25 '19 at 15:03
  • This won't work unfortunately because I need everything inside canvas to scale at once. There is also a zoom in and out feature being used with panzoom. I did change the var to be dynamic though, should have done that to begin with...actually I have an idea I will try and post back. – 5kyt3k Oct 25 '19 at 15:41
  • So it turns out that a 2px boarder around the canvas was causing the problem. So silly. Maybe this will help someone down the road but snapping does work with the panzoom (except with a border around the container element) – 5kyt3k Oct 28 '19 at 19:59
  • Ah. Try putting the canvas inside of a div, the div will have the same background and border, but the canvas will not, this way there is no margin, padding, or border affecting the canvas. – Souleste Oct 28 '19 at 20:05

0 Answers0