2016-03-13 5 views
0

То, что я хочу достичь, - это возможность панорамирования всего изображения «SVG» во время операции перетаскивания.Панорама при перетаскивании в D3JS

Сейчас я играю в этом примере: https://bl.ocks.org/mbostock/6123708, поскольку я нашел его наиболее подходящим для меня (в основном потому, что он управляет перетаскиванием «правильно», большинство других примеров просто центрируют точку во время операции перетаскивания. Я буду перетаскивать более сложный объект, так что мне эта особенность я увеличиваю положение не изменится он больше подходит), но на самом деле не знаю, как я мог бы справиться с этой функцией панорамирования во время перетаскивания

  1. пользователь начнет тянуть круг USIN LeftMouseButton
  2. держит эту кнопку нажать RightMouseButton (затем начинается волшебство)
  3. весь SVG начинает перемещаться (панорамирование) и, таким образом, перетаскиваемый элемент (перетаскивание по-прежнему работает и обновляет положение, так что положение мыши над элементом перетаскивания не изменяется)
  4. пользователь освобождает RightMouseButton, SVG останавливает панорамирование и только сопротивление все еще работает
  5. релиз пользователя для LeftMouseButton и элементы сопротивления обновить его положение

Насколько я знаю, что я должен:

  • обрабатывать сковороду только для RightMouseButton - решаемые
  • обрабатывать Drag только для LeftMouseButton - в разработке :)
  • позволяют Pan начать, когда я нахожусь в перетащить «режим» - это самый вопрос
  • не позволяют вызвать контекстное меню, когда релиз RightMenuButton - решаемые

Извините за английские ошибки это не мой родные один, павшими свободно задавать любые вопросы, которые могли бы решить эту проблему :)

Update

На данный момент я заканчиваю с Souch код для перетаскивания:

var drag = d3.behavior.drag() 
    .on("dragstart", function() { 

    //d3.event.sourceEvent.stopPropagation(); 
    d3.select(this).classed("dragging", true); 

    }).on("drag", function() { 

    var $this = d3.select(this); 
    var t = d3.transform($this.attr("transform")); 
    t.translate[0] += d3.event.dx; 
    t.translate[1] += d3.event.dy; 

    $this.attr("transform", "translate(" + t.translate + ")"); 

    }).on("dragend", function() { 

    console.log("dragend"); 
    d3.select(this).classed("dragging", false); 

    }); 

И Souch для увеличения:

var zoom = d3.behavior.zoom() 
      .scaleExtent([0.1, 2]) 
      .on("zoomstart", function() { 

       if (d3.event.sourceEvent.buttons != 2) { 
        savedTranslation = zoom.translate(); 
       } else { 
        savedTranslation = null; 
       } 

      }).on("zoom", function() { 

       var translate = d3.event.translate; 

       if (d3.event.sourceEvent.buttons != 2) { 
        zoom.translate(savedTranslation); 
        translate = savedTranslation; 
       } 

       svgContainer.attr("transform", "translate(" + translate + ")scale(" + d3.event.scale + ")"); 

      }).on("zoomend", function() { 

       if (savedTranslation) { 
        zoom.translate(savedTranslation); 
        savedTranslation = null; 
       } 

      }); 

Использование зума + предотвратить контекстное меню (также блокировать двойной щелчок для увеличения масштаба, как это будет использовать для вызова редактировать всплывающие модальный)

var svg = d3.select("#svg-workspace") 
      .call(zoom) 
      .on("dblclick.zoom", null) 
      .on('contextmenu',function() { 
       d3.event.preventDefault(); 
       return false; 
      }); 

И присоединять оды D3.JS

d3.select($foreignObject.get(0)) 
    .call(drag); 

в $ foreignObject является JQuery схватил объект

И зачёте проблема начать панорамирование при перемещении.

ответ

0

Это, вероятно, очень трудно достичь в D3JS, поэтому я получаю код JS.На самом деле полезно была эта страница: http://www.petercollingridge.co.uk/interactive-svg-components/pan-and-zoom-control

var transMatrix = [1,0,0,1,0,0]; 

var $svg = $("#svg-workspace"); 

mapMatrix = $("#svg-workspace-group")[0]; 

function pan(dx, dy) 
{ 
    transMatrix[4] += dx; 
    transMatrix[5] += dy; 

    newMatrix = "matrix(" + transMatrix.join(' ') + ")"; 
    mapMatrix.setAttributeNS(null, "transform", newMatrix); 
} 

    function zoom(scale, mousex, mousey) 
    { 
     for (var i=0; i < transMatrix.length; i++) 
     { 
      transMatrix[i] *= scale; 
     } 

     transMatrix[4] += (1-scale) * mousex; 
     transMatrix[5] += (1-scale) * mousey; 

     newMatrix = "matrix(" + transMatrix.join(' ') + ")"; 
     mapMatrix.setAttributeNS(null, "transform", newMatrix); 
} 

$svg.contextmenu(function() {return false;}); 

var drag = false; 
var distanceX = 0; 
var distanceY = 0; 

var initX = 0; 
var initY = 0; 

$svg.on("mousedown", function(evt) { 
    if(evt.originalEvent.which == 1) { 
    drag = true; 
    distanceX = 0; 
    distanceY = 0; 
    } 
}); 

$svg.on("mouseup", function(evt) { 
    if (evt.originalEvent.which == 1) { 
    drag = false; 
    initX = parseInt($("#dragtest").attr("cx")); 
    initY = parseInt($("#dragtest").attr("cy")); 
    } 
}); 

$svg.on("mousemove", function(evt) { 
    if((evt.originalEvent.buttons & 2) == 2) { 
    pan(evt.originalEvent.movementX, evt.originalEvent.movementY); 
    } else if(drag) { 
    distanceX += evt.originalEvent.movementX; 
    distanceY += evt.originalEvent.movementY; 

    $("#dragtest").attr("cx", initX + distanceX/transMatrix[0]); 
    $("#dragtest").attr("cy", initY + distanceY/transMatrix[0]); 
    } 
}); 

$svg.on("mousewheel", function(evt) { 
    if(evt.originalEvent.deltaY > 0) { 
    zoom(0.9, evt.originalEvent.offsetX, evt.originalEvent.offsetY); 
    } else if (evt.originalEvent.deltaY < 0) { 
    zoom(1.1, evt.originalEvent.offsetX, evt.originalEvent.offsetY); 
    } 
}); 

Соответствующий HTML код:

<svg id="svg-workspace" xmlns="http://www.w3.org/2000/svg" width="900" height="600" viewBox="0 0 900 600" style="display: block; margin: 0 auto; border: 1px solid #ddd;"> 
    <g id="svg-workspace-group" transform="translate(0,0)scale(1)"> 
    <circle cx="0" cy="0" r="5" stroke="black" stroke-width="1" fill="red" /> 
    <circle cx="100" cy="-100" r="5" stroke="black" stroke-width="1" fill="red" /> 
    <circle cx="100" cy="100" r="5" stroke="black" stroke-width="1" fill="red" /> 
    <circle cx="-100" cy="100" r="5" stroke="black" stroke-width="1" fill="red" /> 
    <circle id="dragtest" cx="-100" cy="-100" r="5" stroke="black" stroke-width="1" fill="red" /> 
    </g> 
</svg> 

Я нашел только один вопрос с этим кодом Перетаскивание не работает должным образом с масштабированием, но да, я мог бы жить с этим;)

Смежные вопросы