我正在使用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)"
,因为它太复杂而无法解析它
答案 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玩这个免费转换的关键点(如果你想看到它,你可以查看源码)。
不确定这是否有帮助,纯粹用矩阵摆弄是很难跟踪的。我也存储了原始变换,部分原因是任何导入的对象可能已经应用了变换,但在编辑时也将其保留为更新。