使用 SVG 在同一变换下组合两个矩阵变换
Combining two Matrix Transformations under the same Transformation with SVG
我目前的任务是尝试在相同的变换矩阵下将具有相似矩阵的对象组合起来。这两个矩阵的变换的前 4 位数字总是相等的。我在计算 x="???" 时遇到困难和 y="???对于第二个 tspan。任何对正确方程式的帮助将不胜感激。
输入
<svg>
<text transform="matrix(0 1 1 0 100 100)"><tspan x=0 y=0>foo</tspan></text>
<text transform="matrix(0 1 1 0 110 110)"><tspan x=0 y=0>bar</tspan></text>
</svg>
输出
<svg>
<text transform="matrix(0 1 1 0 100 100)">
<tspan x="0" y="0">foo</tspan>
<tspan x="???" y="???">bar</tspan>
</text>
</svg>
编辑 1
我想我的问题更多的是给定一个点 (x,y),我如何将现有的矩阵变换应用到那个点,这样位置就不会移动,但元素现在将被嵌套在另一个元素内。
编辑 2
我已获得此代码,适用于 (a,d) 或 (b,c) 位置为 0 的矩阵。 Slanted/Skewed 矩阵我还没有开始工作。对此有什么想法吗?
var aX = floatX[0];
var bX = floatX[1];
var cX = floatX[2];
var dX = floatX[3];
var eX = floatX[4];
var fX = floatX[5];
var aY = floatY[0];
var bY = floatY[1];
var cY = floatY[2];
var dY = floatY[3];
var eY = floatY[4];
var fY = floatY[5];
var xX = (eX * aX) + (fX * bX);
var xY = (eX * cX) + (fX * dX);
var yX = (eY * aY) + (fY * bY);
var yY = (eY * cY) + (fY * dY);
var c1 = cX - aX;
var c2 = dX + bX;
return new float[] { (yX - xX) / (c1 * c2), (yY - xY) / (c1 * c2) };
如果我的逻辑没有缺陷,一个想法可能会奏效,那就是找到一个元素到另一个元素的变换,然后可以用它来变换点 0,0(因为那是原始 x, y) 到新位置。
一旦我们知道变换的区别是什么(假设矩阵中的前 4 个数字与问题中提到的相同,否则它将不起作用),我们可以计算出 x 的区别,你是。
首先,有一些代码,因为一些浏览器已经删除了这个功能..
SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(elem) {
return elem.getScreenCTM().inverse().multiply(this.getScreenCTM());
};
这是一些浏览器支持的 svg 方法,但作为 polyfill 包括在内,以防您的浏览器不支持(例如 Chrome)。它找到从一个元素到另一个元素的转换。
然后我们可以使用它来找到从第一个文本元素到第二个文本元素的转换。
var text1 = document.querySelector('#myText1')
var text2 = document.querySelector('#myText2')
var transform = text2.getTransformToElement( text1 )
或者,如果您不想要 polyfill,这个 'may' 可行(矩阵不是我的强项!)。 getCTM() 获取当前元素的变换矩阵
var transform = text1.getCTM().inverse().multiply( text2.getCTM() )
现在我们知道它们之间的转换是什么了。我们也知道原来的 x,y 是 0,0。所以我们可以创建一个 svg 点 0,0,然后用我们刚刚算出的矩阵对其进行转换,以找到新的 x,y。
var pt = document.querySelector('svg').createSVGPoint();
pt.x = 0; pt.y = 0;
var npt = pt.matrixTransform( transform );
然后只是一个延迟的例子来显示它正在被移动。将 tspan 设置为新的 x,y 我们刚刚从之前的转换中得出。
setTimeout( function() {
alert('new x,y is ' + npt.x + ',' + npt.y)
tspan2.setAttribute('x', npt.x);
tspan2.setAttribute('y', npt.y);
},2000);
jsfiddle 与 polyfill
jsfiddle 没有 polyfill
我目前的任务是尝试在相同的变换矩阵下将具有相似矩阵的对象组合起来。这两个矩阵的变换的前 4 位数字总是相等的。我在计算 x="???" 时遇到困难和 y="???对于第二个 tspan。任何对正确方程式的帮助将不胜感激。
输入
<svg>
<text transform="matrix(0 1 1 0 100 100)"><tspan x=0 y=0>foo</tspan></text>
<text transform="matrix(0 1 1 0 110 110)"><tspan x=0 y=0>bar</tspan></text>
</svg>
输出
<svg>
<text transform="matrix(0 1 1 0 100 100)">
<tspan x="0" y="0">foo</tspan>
<tspan x="???" y="???">bar</tspan>
</text>
</svg>
编辑 1
我想我的问题更多的是给定一个点 (x,y),我如何将现有的矩阵变换应用到那个点,这样位置就不会移动,但元素现在将被嵌套在另一个元素内。
编辑 2
我已获得此代码,适用于 (a,d) 或 (b,c) 位置为 0 的矩阵。 Slanted/Skewed 矩阵我还没有开始工作。对此有什么想法吗?
var aX = floatX[0];
var bX = floatX[1];
var cX = floatX[2];
var dX = floatX[3];
var eX = floatX[4];
var fX = floatX[5];
var aY = floatY[0];
var bY = floatY[1];
var cY = floatY[2];
var dY = floatY[3];
var eY = floatY[4];
var fY = floatY[5];
var xX = (eX * aX) + (fX * bX);
var xY = (eX * cX) + (fX * dX);
var yX = (eY * aY) + (fY * bY);
var yY = (eY * cY) + (fY * dY);
var c1 = cX - aX;
var c2 = dX + bX;
return new float[] { (yX - xX) / (c1 * c2), (yY - xY) / (c1 * c2) };
如果我的逻辑没有缺陷,一个想法可能会奏效,那就是找到一个元素到另一个元素的变换,然后可以用它来变换点 0,0(因为那是原始 x, y) 到新位置。
一旦我们知道变换的区别是什么(假设矩阵中的前 4 个数字与问题中提到的相同,否则它将不起作用),我们可以计算出 x 的区别,你是。
首先,有一些代码,因为一些浏览器已经删除了这个功能..
SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function(elem) {
return elem.getScreenCTM().inverse().multiply(this.getScreenCTM());
};
这是一些浏览器支持的 svg 方法,但作为 polyfill 包括在内,以防您的浏览器不支持(例如 Chrome)。它找到从一个元素到另一个元素的转换。
然后我们可以使用它来找到从第一个文本元素到第二个文本元素的转换。
var text1 = document.querySelector('#myText1')
var text2 = document.querySelector('#myText2')
var transform = text2.getTransformToElement( text1 )
或者,如果您不想要 polyfill,这个 'may' 可行(矩阵不是我的强项!)。 getCTM() 获取当前元素的变换矩阵
var transform = text1.getCTM().inverse().multiply( text2.getCTM() )
现在我们知道它们之间的转换是什么了。我们也知道原来的 x,y 是 0,0。所以我们可以创建一个 svg 点 0,0,然后用我们刚刚算出的矩阵对其进行转换,以找到新的 x,y。
var pt = document.querySelector('svg').createSVGPoint();
pt.x = 0; pt.y = 0;
var npt = pt.matrixTransform( transform );
然后只是一个延迟的例子来显示它正在被移动。将 tspan 设置为新的 x,y 我们刚刚从之前的转换中得出。
setTimeout( function() {
alert('new x,y is ' + npt.x + ',' + npt.y)
tspan2.setAttribute('x', npt.x);
tspan2.setAttribute('y', npt.y);
},2000);
jsfiddle 与 polyfill
jsfiddle 没有 polyfill