正在为平移期间旋转的 SVG 动画计算 CSS 变换矩阵
Calculating CSS transform matrix for SVG animation of rotation during translation
当沿着直线从红色方块移动到蓝色方块时,方块应该被设置为旋转动画。我无法让它工作,正如你从移动的方块中看到的那样与固定的蓝色方块不匹配。
这个问题反复出现,因此我需要一个可重复使用的解决方案。也就是说:不仅要给出矩阵的具体数字,还要给出得出这些值的计算方法。
所以我需要根据以下变量进行 matrix()
转换:
x1,y1
为直线运动路径的起点(下例75,75
);
x2,y2
为直线运动路径的终点(下例175,75
);
cx,cy
为旋转中心(下例75,75
);
a
作为旋转的角度(在下面的示例中 45deg
- 我更愿意以弧度给出值,但 CSS 似乎不接受);
使得物体绕cx,cy
旋转角度a
而点x1,y1
沿直线移动到x2,y2
(注意当x1,y1
和 cx,cy
在下面的示例中重合,但情况并非总是如此,但示例应该很简单)。
请注意,我确实知道矩阵的工作原理,包括如何组合变换。问题是我不知道这个特定问题需要哪些特定转换。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="250px" height="150px" viewBox="0 0 250 150">
<style>
*{stroke:black;stroke-width:1px;}
@keyframes ani {
0% {fill:#f00;transform:translate(0, 0 );}
/* illustrating that movement works without rotation. */
25% {fill:#00f;transform: translate( 100px, 0 );}
50% {fill:#f00;transform:translate(0, 0 );}
/* with rotation it ends up anywhere but where it is supposed to go. */
75% {fill:#00f;transform: translate( 100px, 0 ) translate( 175px, 75px) rotate( 45deg ) translate( -175px, -75px );}
100% {fill:#f00;transform:translate(0, 0 );}
}
#p {animation: ani 4000ms ease-in-out 10ms infinite normal forwards;}
</style>
<defs>
<path id="def" d="m0,0 l50,0 l0,50 l-50,0 l0,-50" />
</defs>
<use xlink:href="#def" x="50" y="50" style="fill:#faa;" />
<use xlink:href="#def" x="150" y="50" style="fill:#aaf;" transform="rotate( 45 175 75 )" />
<use id="p" xlink:href="#def" x="50" y="50" />
</svg>
我相信你想要的矩阵基本上是这样的(感谢this page帮我弄清楚):
transform: matrix(cos(angle),sin(angle),-sin(angle),cos(angle),translateDiffX,translateDiffY);
我不认为你可以在 CSS 中设置三角函数值(除了预处理器),所以我做了 this fiddle CSS 被 JavaScript 覆盖(尽管以一种粗暴的方式),并更改了角度和平移值以进行测试以确保它适用于其他情况。
请注意,在 0% 和 100% 处没有 transform-origin
时,动画会有一种弧形效果(尽管可能是 desirable/unimportant)。
当沿着直线从红色方块移动到蓝色方块时,方块应该被设置为旋转动画。我无法让它工作,正如你从移动的方块中看到的那样与固定的蓝色方块不匹配。
这个问题反复出现,因此我需要一个可重复使用的解决方案。也就是说:不仅要给出矩阵的具体数字,还要给出得出这些值的计算方法。
所以我需要根据以下变量进行 matrix()
转换:
x1,y1
为直线运动路径的起点(下例75,75
);x2,y2
为直线运动路径的终点(下例175,75
);cx,cy
为旋转中心(下例75,75
);a
作为旋转的角度(在下面的示例中45deg
- 我更愿意以弧度给出值,但 CSS 似乎不接受);
使得物体绕cx,cy
旋转角度a
而点x1,y1
沿直线移动到x2,y2
(注意当x1,y1
和 cx,cy
在下面的示例中重合,但情况并非总是如此,但示例应该很简单)。
请注意,我确实知道矩阵的工作原理,包括如何组合变换。问题是我不知道这个特定问题需要哪些特定转换。
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<svg xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="250px" height="150px" viewBox="0 0 250 150">
<style>
*{stroke:black;stroke-width:1px;}
@keyframes ani {
0% {fill:#f00;transform:translate(0, 0 );}
/* illustrating that movement works without rotation. */
25% {fill:#00f;transform: translate( 100px, 0 );}
50% {fill:#f00;transform:translate(0, 0 );}
/* with rotation it ends up anywhere but where it is supposed to go. */
75% {fill:#00f;transform: translate( 100px, 0 ) translate( 175px, 75px) rotate( 45deg ) translate( -175px, -75px );}
100% {fill:#f00;transform:translate(0, 0 );}
}
#p {animation: ani 4000ms ease-in-out 10ms infinite normal forwards;}
</style>
<defs>
<path id="def" d="m0,0 l50,0 l0,50 l-50,0 l0,-50" />
</defs>
<use xlink:href="#def" x="50" y="50" style="fill:#faa;" />
<use xlink:href="#def" x="150" y="50" style="fill:#aaf;" transform="rotate( 45 175 75 )" />
<use id="p" xlink:href="#def" x="50" y="50" />
</svg>
我相信你想要的矩阵基本上是这样的(感谢this page帮我弄清楚):
transform: matrix(cos(angle),sin(angle),-sin(angle),cos(angle),translateDiffX,translateDiffY);
我不认为你可以在 CSS 中设置三角函数值(除了预处理器),所以我做了 this fiddle CSS 被 JavaScript 覆盖(尽管以一种粗暴的方式),并更改了角度和平移值以进行测试以确保它适用于其他情况。
请注意,在 0% 和 100% 处没有 transform-origin
时,动画会有一种弧形效果(尽管可能是 desirable/unimportant)。