如何在Javascript中更新SVG元素的转换?

时间:2014-09-08 17:54:51

标签: javascript svg transformation snap.svg

我正在使用SVG和Snap.SVG库编写一个简单的可视化编辑器。 它有一堆复杂的形状作为模板,每个形状都是一个包含路径的<g>元素。

编辑器允许用户通过移动,缩放和旋转形状来变换形状。 这是通过将变换应用为每个形状的主<g>元素上的矩阵来完成的。 数学主要由Snap.SVG库完成。

变换必须按特定顺序应用才能使事物看起来正确。用户可以按他们喜欢的任何顺序进行任何变换。因此,每个用户与形状的交互都是对该形状的变换矩阵的更新。

当用户移动,旋转,缩放,再次旋转并再次缩放时,更新形状上的变换矩阵并保持变换的正确顺序的最佳方法是什么?

目前,所有转换都按以下顺序完成:translate => rotate => scale。在这种情况下,在比例已经应用于矩阵之后更新旋转角度会破坏形状。因为已经考虑了比例来计算矩阵。它将变为translate => rotate => scale => rotate,最后一次旋转将被缩放变换拉伸。

我试图避免存储有关变换的任何额外数据(例如,在data-属性中)并且还避免使用变换字符串,例如transform="translate(x, y) rotate(a, x, y) scale(x, y)",因为它太复杂而无法解析它

1 个答案:

答案 0 :(得分:2)

我只能真正建议我之前所做的工作。

这是我前一段时间做的一个例子的代码...(最初来自插件,但是当涉及到订单时,updateTransform函数是关键位)

    Element.prototype.ftStoreInitialTransformMatrix = function() {
        this.data('initialTransformMatrix', this.transform().localMatrix );
        return this;
    };

    Element.prototype.ftGetInitialTransformMatrix = function() {
        return this.data('initialTransformMatrix');
    };

    Element.prototype.ftUpdateTransform = function() {
        var tstring = "t" + this.data("tx") + "," + this.data("ty") + this.ftGetInitialTransformMatrix().toTransformString() + "r" + this.data("angle") + 'S' + this.data("scale" );        
        this.attr({ transform: tstring });
        return this;
    };

这些是我使用here玩这个免费转换的关键点(如果你想看到它,你可以查看源码)。

不确定这是否有帮助,纯粹用矩阵摆弄是很难跟踪的。我也存储了原始变换,部分原因是任何导入的对象可能已经应用了变换,但在编辑时也将其保留为更新。