嵌套SVG <g>元素旋转异常:子元素旋转枢轴不符合预期
SVG嵌套旋转异常的解决方案
你的问题出在SVG的坐标系变换叠加逻辑上:父rotate会改变子元素所在的局部坐标系,子rotate(angle2 x2 y2)里的x2,y2是父变换后的坐标系坐标,而你期望它是原坐标系的点,这就导致了旋转结果不符合预期。
不用非得把子
方法1:转换子元素旋转的枢轴坐标
把原坐标系中的x2,y2转换为父变换后的局部坐标系坐标,再作为子rotate的参数。可以用以下公式计算转换后的坐标(假设angle1是父旋转角度,单位为度):
const rad1 = angle1 * Math.PI / 180; // 转换原坐标(x2,y2)到父局部坐标系 const xPrime = (x2 - x1) * Math.cos(rad1) + (y2 - y1) * Math.sin(rad1) + x1; const yPrime = -(x2 - x1) * Math.sin(rad1) + (y2 - y1) * Math.cos(rad1) + y1;
修改子
<g transform="rotate(angle1 x1 y1)"> <g transform="rotate(angle2 ${xPrime} ${yPrime})"> <path>...</path> </g> </g>
方法2:用transform-origin指定全局枢轴(现代浏览器支持)
给子transform-origin为原坐标系的x2,y2,并指定transform-box: view-box(以SVG视口为参考系),这样旋转不受父坐标系变换的影响:
<g transform="rotate(angle1 x1 y1)"> <g style="transform-origin: ${x2}px ${y2}px; transform-box: view-box;" transform="rotate(angle2)"> <path>...</path> </g> </g>
方法3:分离父子元素的变换(你考虑的方案)
把子
<g transform="rotate(angle1 x1 y1)"> <!-- 父元素其他内容 --> </g> <g transform="rotate(angle1 x1 y1) rotate(angle2 x2 y2)"> <path>...</path> </g>
这样先让子元素跟着父旋转到对应位置,再绕原x2,y2额外旋转angle2度,和你的预期一致。
内容的提问来源于stack exchange,提问作者Louis Emard
相关产品推荐
相关产品推荐

