Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/458.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在SVG上使用skewX和skewY时如何补偿平移_Javascript_Math_Svg_Transform_Skew - Fatal编程技术网

Javascript 在SVG上使用skewX和skewY时如何补偿平移

Javascript 在SVG上使用skewX和skewY时如何补偿平移,javascript,math,svg,transform,skew,Javascript,Math,Svg,Transform,Skew,CONTEXT:@AnaTudor(@daredevil)当使用skewX或skewY时,SVG的d移动距离,因此我想知道是否有任何方法可以计算该距离以补偿平移,并避免使用链式translate 测试用例:在下面的snipet中,我们不会使用SVG特定的链接和/或嵌套,我们只使用相同的转换值,而是按照转换函数的特定顺序使用 左绿色矩形通过样式:平移,旋转,倾斜,倾斜,缩放 右橄榄形矩形通过变换属性:平移,缩放,旋转,倾斜,`skewY 现在,正如你所看到的,这两个矩形有不同的定位,如果你点击

CONTEXT:@AnaTudor(@daredevil)当使用
skewX
skewY
时,SVG的
d
移动距离,因此我想知道是否有任何方法可以计算该距离以补偿平移,并避免使用链式
translate

测试用例:在下面的snipet中,我们不会使用SVG特定的链接和/或嵌套,我们只使用相同的转换值,而是按照转换函数的特定顺序使用

  • 左绿色矩形通过
    样式
    平移
    旋转
    倾斜
    倾斜
    缩放
  • 右橄榄形矩形通过
    变换
    属性:
    平移
    缩放
    旋转
    倾斜
    ,`skewY
现在,正如你所看到的,这两个矩形有不同的定位,如果你点击按钮,第二个矩形将更接近我们预期的,但仍然需要对所有情况进行更多计算

问题:我们如何更改
fixOrigin
函数来调整所有可能的转换函数组合的转换,方法与CSS3转换相同

var el1=document.querySelectorAll('path')[0],
el2=document.querySelectorAll('path')[1],
el2BB=el2.getBBox(),el2cx=el2BB.x+el2BB.width/2,el2cy=el2BB.y+el2BB.height/2,
btn=document.querySelectorAll('button')[0],btn1=document.querySelectorAll('button')[1],
x=20,y=20,比例=0.6,旋转=45,倾斜x=20,倾斜=-20;
el1.style.transform='平移(20px,20px)旋转(45度)倾斜x(20度)倾斜(-20度)缩放(0.6)';
el1.style.transformOrigin='50%50%0px';
el2.setAttribute('transform'、'translate('+x+'、'+y+')scale('+scale+'))rotate('+rotate+'+el2cx+'、'+el2cy+'))skewX('+skewX+'))skewY('+skewY+');
函数fixOrigin(){
x+=(1-刻度)*el2BB.宽度/2;
y+=(1-刻度)*el2BB.高度/2;
el2.setAttribute('transform'、'translate('+x+'、'+y+')scale('+scale+'))rotate('+rotate+'+el2cx+'、'+el2cy+'))skewX('+skewX+'))skewY('+skewY+');
}
btn.addEventListener('click',fixOrigin,false);
函数fixEverything(){
//scale将所有变换函数绑定在一起
如果(!!比例){
//最重要的是确保我们有翻译价值
//!!(x)和&(x=0);!!(y)和&(y=0);
//首先根据比例值调整平移
x+=(1-刻度)*el2BB.宽度/2;
y+=(1-刻度)*el2BB.高度/2;
//现在,我们还根据倾斜调整旋转变换原点
如果(!!旋转){
//el2cx+=…el2cy+=。。。
}
//差不多了,现在我们根据倾斜调整平移
//x+=…y+=。。。
//最后一种情况是单独使用倾斜
}否则,如果(!缩放和旋转){
//在这里调整翻译
//x+=…y+=。。。
}
el2.setAttribute('transform'、'translate('+x+'、'+y+')scale('+scale+'))rotate('+rotate+'+el2cx+'、'+el2cy+'))skewX('+skewX+'))skewY('+skewY+');
}
btn1.addEventListener('click',FixeEverything,false)
/*所需的转换
变换原点:50%50%0px;
变换:平移(20px,20px)旋转(45度)倾斜(20度)倾斜(-20度)缩放(0.6);
*/
svg{
溢流:可见;宽度:30%;
边框:1px实心#eee;/*某种标尺*/
}
Fix-Transform-OriginFix-All
单击以更改“transform”属性


因为您当前的核心问题似乎是如何计算
d
距离。它来自一次谈话,其中歪斜操作基本上被描述为(x,y)↦ (x+d,y)对于
skewX
的情况。如果你看一看,你会发现一个矩阵,它本质上说
skewX(a)
的精确公式是
(x,y)↦ (x+cos(a)y,y)
。同样地,对于
skewY(a)
你有
(x,y)↦ (x,y+cos(a)x)
。因此,在第一种情况下,
d:=cos(a)*y
,在第二种情况下,
d:=cos(a)*x

不过,问题的标题向我提出了一个不同的问题。这个问题可以表述如下:给定
transform=“skewX(c)translate(a,b)”
对于一些数字
a
b
c
,找到
d
e
,这样我刚才给出的转换与
translate(d,e)skewX(c)
相同。或者换句话说:如果要将变换移动到
skewX
的外部,我必须如何更改
变换的条目

要查找这些数字,请查看相应的矩阵乘积,如下所示:

所以你有
d=a+tan(c)*b
e=b
。只需将倾斜变换应用于平移向量。换言之:

skewX(c) translate(a, b) = translate(a + tan(c) * b, b) skewX(c)
您可以对
y
执行类似的计算,并获得:

skewY(c) translate(a, b) = translate(a, b + tan(c) * a) skewY(c)

如果将
skewX
skewY
组合在一起,则可以将
translate
一次移出一个步骤,以便在每个步骤中只需处理一个倾斜方向。如果您想要相反的方向(即移动
translate
靠近倾斜的内部),请在这些公式中使用
-tan(c)
而不是
+tan(c)

您编辑的问题及其包含的示例更清楚地表明,您真正想要的是translate CSS3
style=“transform:…”
转换为等效SVG
transform=“…”
转换。特别是以允许CSS3
变换原点:50%50%0px
的方式,将变换中心放置在对象的中心,而不是SVG坐标系的原点

下面的代码片段演示了实现这一点的两种方法。其中一个相当简单:首先平移对象的中心(已平移)
skewY(c) translate(a, b) = translate(a, b + tan(c) * a) skewY(c)
transform="translate(256,256)
           translate(20, 20)
           rotate(45) skewX(20) skewY(-20) scale(0.6)
           translate(-256,-256)"
transform="translate(211.325,73.165)
           rotate(45) skewX(20) skewY(-20) scale(0.6)"