x 和 y 在设置 Transform() 后获得附加值

x and y get added additional value after setting Transform()

我正在研究 svg 自由变换。一切正常,除非对象在页面初始化后有自己的带有缩放值的转换属性。

像这样:

<g transform="matrix(1.5,0,0,1.5,70,70)"></g>

下面是我对这个对象进行拖动和调整大小的操作

var newTransform = 't' + (this.data('xy').x) + ',' + (this.data('xy').y);
                newTransform += 'r' + (this.data('r'))
                newTransform += 's' + (this.data('s'))

this.transform(newTransform);

如果对象没有初始比例值,这可以正常工作,除非。可以完美地拖动和缩放对象。

但是,如果对象一开始就有缩放属性(不等于1),当我设置第一个transform()时,对象会再次缩放。将添加额外的 x、y 和大小。如果我改用矩阵,问题就可以解决。但是对象不会从中心缩放。

用矩阵变换:

   var t = new Snap.Matrix()
   t.add(this.data('s'),0,0,this.data('s'),this.data('xy').x,this.data('xy').y);
   this.transform(t);

我在使用 snap svg 字符串进行转换时做错了什么吗?如何防止第一次转换 (str) 缩放两次?

这可能会变得相当复杂。如果可以合并,最简单的方法是将要拖动的元素放在 g/group 元素内。然后将拖动放在那个外部 g/group 元素上。

这会保留内部元素上的现有转换,并且不会变得混乱。所以如果你可以在 svg 中包含一个额外的组元素,我会走这条路。

如果您出于任何原因不能。我认为从长远来看(特别是如果您将进行包括动态旋转等在内的自由变换),那么我认为您需要变得更加复杂。我包括了一条我可能会使用的起始路线,它也将能够应对缩放的 viewbox/screen,因为这会带来额外的复杂性。

所以我可能会介绍一些新方法...

getCursorPoint 获取鼠标的实际点,说明屏幕上的任何变换(与元素相对)。我不确定您在具体示例中是否需要这个,但是您稍后可能会发现使用放大的纸张或其他东西遇到了这个问题。

getTransformedDrag,考虑拖动时的任何屏幕转换。

Element.prototype.getCursorPoint = function( x, y ) {
    var pt = this.paper.node.createSVGPoint();      
    pt.x = x; pt.y = y;
    return pt.matrixTransform( this.paper.node.getScreenCTM().inverse() ); 
}

Element.prototype.getTransformedDrag = function( otx, oty, x, y ) {
    var xy = this.getCursorPoint( x, y );
    var tdx = {};
    var snapInvMatrix = this.data('origTransform').invert();

    snapInvMatrix.e = snapInvMatrix.f = 0;

    tdx.x = snapInvMatrix.x( xy.x - otx, xy.y - oty );
    tdx.y = snapInvMatrix.y( xy.x - otx, xy.y - oty );
    return tdx;
}

现在我们有一些关于拖动的背景绒毛,我们可以将它们插入到一些元素拖动中....

存储可能的屏幕变换光标位置和元素上的初始矩阵。

var dragStart = function(x, y, ev) {
    this.data('origTransform', this.transform().localMatrix)
    var txy = this.getCursorPoint(x,y)
    this.data('oxy', {x: txy.x, y: txy.y });
}

var dragMove = function(dx, dy, x, y, ev) {
    var tdr = this.getTransformedDrag( this.data('oxy').x, this.data('oxy').y, x, y)
    this.data('xy', {
            x: tdr.x,
            y: tdr.y
        })
    .updateTransform();
}

Element.prototype.updateTransform = function() {
    var newTransform = 't' + (this.data('xy').x) + ',' + (this.data('xy').y);
    //newTransform += 'r' + (this.data('r'))
    //newTransform += 's' + (this.data('s'))
    this.transform(this.data('origTransform').toTransformString() + newTransform )

    return this;
}

Example jsfiddle

如前所述,这似乎过于复杂,但我只是想包含一些您以后可能会发现有用的额外代码,因为这是一个相当复杂的领域。所以当你需要的时候就把这个作为参考吧。