当前位置: 代码迷 >> JavaScript >> Snap.svg缩放时拖动
  详细解决方案

Snap.svg缩放时拖动

热度:89   发布时间:2023-06-13 11:44:38.0

当我在缩放(缩放)的对象上使用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 );

参见提琴(只需拖动其中一个形状)

TIA!

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

这是我前一段时间做过的插件,以帮助解决此问题。

主要位是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() {
    }
});

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

基本实现:

  1. Scale是一个全局变量(也可以是FLOAT)
  2. 所有dxdy运动都除以Scale

旁注:所有元素都可以拖出框。 您可能需要对边缘进行一些移动限制。

在这里,我使用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;   
}

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