如何在Javascript中更新SVG元素上的转换?
我正在使用SVG和Snap.SVG库开发一个简单的可视化编辑器。 它有一组复杂的形状作为模板,每个形状都是一个包含路径的如何在Javascript中更新SVG元素上的转换?,javascript,svg,transformation,snap.svg,Javascript,Svg,Transformation,Snap.svg,我正在使用SVG和Snap.SVG库开发一个简单的可视化编辑器。 它有一组复杂的形状作为模板,每个形状都是一个包含路径的元素 编辑器允许用户通过移动、缩放和旋转形状来变换形状。 这是通过将变换作为矩阵应用于每个形状的主元素来实现的。 数学运算主要由Snap.SVG库完成 变换必须按特定顺序应用,才能使事情看起来正确。用户可以按照自己喜欢的顺序进行任何转换。因此,每个用户与形状的交互都是该形状变换矩阵的更新 当用户移动、旋转、缩放、再次旋转和再次缩放时,更新形状上的变换矩阵并保持变换正确顺序的最佳
元素
编辑器允许用户通过移动、缩放和旋转形状来变换形状。
这是通过将变换作为矩阵应用于每个形状的主
元素来实现的。
数学运算主要由Snap.SVG库完成
变换必须按特定顺序应用,才能使事情看起来正确。用户可以按照自己喜欢的顺序进行任何转换。因此,每个用户与形状的交互都是该形状变换矩阵的更新
当用户移动、旋转、缩放、再次旋转和再次缩放时,更新形状上的变换矩阵并保持变换正确顺序的最佳方法是什么
目前,所有转换都是按照以下顺序进行的:translate=>rotate=>scale
。在这种情况下,在将比例应用于矩阵后更新旋转角度将破坏形状。因为矩阵的计算已经考虑了比例。它将变成translate=>rotate=>scale=>rotate
,最后一次旋转将被scale变换拉伸
我试图避免存储任何有关转换的额外数据(例如在
数据-
属性中),也避免使用转换字符串,例如transform=“translate(x,y)rotate(a,x,y)scale(x,y)”
,因为解析它太复杂了。我只能就我之前所做的工作给出建议
这是我不久前做的一个示例中的代码位…(最初来自一个插件,但对于订单而言,updateTransform函数是关键)
这些是我在玩这个自由变换的东西时做的关键点(如果你想全部看到,你可以查看源代码)
不确定这是否有帮助,单纯地摆弄矩阵是很难跟踪的。我还存储了原始变换,部分原因是任何导入的对象都可能已经应用了变换,但在编辑时也会将其作为更新保存。我真的不知道如果只使用矩阵,如何将它们保持有序。如果您想按顺序存储它们,我认为您所能做的就是将其存储在以字符串形式构建的快照转换中('t10,10r20,s2,t20,20'等)。矩阵也很难使用。就我个人而言,我会将平移、旋转、缩放存储为数据元素,但你说你不想这样做(不知道为什么)。实际上,我并不打算以任何特定的方式来做。我愿意接受任何建议。在我看来,为它保留额外的属性可能是多余的,可能有更好的方法。我正在寻找一种“最佳实践”方式。我也不知道为什么我在网上找不到关于这个的任何东西。我不可能是第一个这样做的人/谢谢你的帮助。最后,我将转换字符串保存在相关元素的属性中。使用Snap.parseTransformString,我从该字符串获取transforms数组,对其进行操作并将其转换回转换字符串。因为我将SVG标记保存到数据库中,所以转换将保持不变,并且我能够在以后需要时修改它们。由于Snap.parseTransformString返回一个数组,所以我可以按照我想要的任何方式对转换进行排序,并在更改其中一个转换时保持顺序。
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;
};