设置Transform()后,x和y会添加其他值

问题描述 投票:0回答:1

我正在研究svg free transform。一切正常,除非对象在页面初始化后具有自己的具有缩放值的transform属性。

像这样的东西:

<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);

如果对象没有初始缩放值,则此方法可以正常工作。可以完美地拖动和缩放对象。

但是,如果对象在开头有scale属性(不等于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 string进行转换时做错了吗?如何防止第一次变换(str)的缩放两次?

snap.svg
1个回答
0
投票

这可能变得非常复杂。如果可以合并的话,最简单的方法是将元素放置在g / group元素内。然后将拖动放在外部g / group元素上。

这样可以保持内部元素的现有转换,并且不会变得混乱。因此,如果你可以在svg中包含一个额外的组元素,我会选择这条路线。

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

所以我可能会介绍几种新方法......

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

如上所述,这可能看起来过于复杂,但我只想尝试包含一些你以后可能会发现有用的额外代码,因为它是一个非常复杂的领域。因此,只需在需要时将其用作参考。

© www.soinside.com 2019 - 2024. All rights reserved.