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

时间:2017-12-27 10:43:49

标签: snap.svg

我正在开发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)的缩放两次?

1 个答案:

答案 0 :(得分: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

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