Snap.svg放大时拖动

时间:2015-07-17 21:03:45

标签: javascript svg transform snap.svg

当我在缩放(缩放)对象上使用drag()时,对象会根据比例移动,因此,例如,如果比例设置为3 - 则鼠标的每次1px移动乘以3

用鼠标移动大约20个像素后,行为是完全不可接受的。

这是一个错误还是我做错了什么?

var g = s.g();
g.transform("scale(3)");

var rect = g.rect(20,20,40,40);
var circle = g.circle(60,150,50);

var move = function(dx,dy) {
    this.attr({
        transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx, dy]
    });
}

var start = function() {
    this.data('origTransform', this.transform().local );
}
var stop = function() {
    console.log('finished dragging');
}

rect.drag(move, start, stop );
circle.drag(move, start, stop );

http://jsfiddle.net/mje8knLf/1/看小提琴(只需拖动其中一个形状)

TIA!

3 个答案:

答案 0 :(得分:2)

为此,我们需要考虑所有外部元素上出现的现有转换。

这是一个插件,我做了一段时间回来帮助解决这个问题。

主要部分是dragMove功能。我们发现现有的其他变换(在元素上的Snap中有3种类型的变换矩阵,localMatrix,diffMatrix,globalMatix),并将其反转以获得我们想要应用的矩阵以允许现有效果。 (如果在某些情况下diffMatrix不起作用,请查看globalMatrix)。

然后使用它,我们可以在新的拖动量上使用y()和x()来查找新坐标空间中的内容。

Snap.plugin( function( Snap, Element, Paper, global ) {

    Element.prototype.altDrag = function() {
        this.drag( dragMove, dragStart, dragEnd );
        return this;
    }

    var dragStart = function ( x,y,ev ) {
            this.data('ot', this.transform().local );
    }

    var dragMove = function(dx, dy, ev, x, y) {
            var tdx, tdy;
            var snapInvMatrix = this.transform().diffMatrix.invert();
            snapInvMatrix.e = snapInvMatrix.f = 0;
            tdx = snapInvMatrix.x( dx,dy ); tdy = snapInvMatrix.y( dx,dy );
            this.transform( "t" + [ tdx, tdy ] + this.data('ot')  );

    }

    var dragEnd = function() {
    }
});

答案 1 :(得分:1)

尝试:transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [dx/3, dy/3]

基本实施: -

  1. Scale是一个全局变量(也可以是FLOAT)
  2. 所有dxdy动作除以Scale
  3. 旁注:所有元素都可以直接拖出。您可能希望在边缘周围实现一些移动限制。

答案 2 :(得分:0)

在这里,我使用svg-pan-zoom.js进行SVG的平移和缩放,非常易于使用。 我正在使用snap.svg

var svgElement;
var panZoomPlan;
function setPanZoom(){
    svgElement = document.querySelector('svg');
    panZoomPlan = svgPanZoom(svgElement);   

    panZoomPlan.setMinZoom(0.1);
    panZoomPlan.setMaxZoom(50);
    panZoomPlan.setZoomScaleSensitivity(0.2);
    panZoomPlan.disableDblClickZoom();      
}

function set_draggable(svg_element) {
    var shape = plan.select("#" + svg_element);
    shape.drag(dragNode, dragStart, dragStop);
}

var dragStart = function() {    
    panZoomPlan.disablePan();
    panZoomPlan.disableZoom();
    this.isDragged = false;

    var node_id = this.node.id;

    this.data('origTransform', this.transform().local );
}       

var dragNode = function(dx,dy) {
    this.isDragged = true;
    realZoom = panZoomPlan.getSizes().realZoom;
    var rdx = dx/realZoom;
    var rdy = dy/realZoom;

    this.attr({
        transform: this.data('origTransform') + (this.data('origTransform') ? "T" : "t") + [rdx, rdy]
    });

    event.preventDefault();
}

var dragStop = function() {
    panZoomPlan.enablePan();
    panZoomPlan.enableZoom();

    if (!this.isDragged) { 
        return;
    }

    //update scene elements data
    var node_id = this.node.id;
    Nodes_dict[node_id].x += Nodes_dict[node_id].rdx; 
    Nodes_dict[node_id].y += Nodes_dict[node_id].rdy;   
}

我希望这对以后看到此问题的用户有所帮助。