动画 SVG 组对象 - 使用样式组件进行变换旋转不会围绕圆原点旋转
Posted
技术标签:
【中文标题】动画 SVG 组对象 - 使用样式组件进行变换旋转不会围绕圆原点旋转【英文标题】:Animating SVG group object - transform rotate with styled-components doesnt rotate around circle origin 【发布时间】:2021-09-15 16:59:54 【问题描述】:我有一个 SVG 圆圈和一些线条对象,它们制作了一个简单的十字准线鼠标光标,我正在尝试使用样式组件对其进行动画处理。当光标悬停在某些对象上时,我希望光标内的线条元素围绕构成光标的圆形元素的原点旋转。一个 redux useSelector 钩子可以访问被悬停的组件的 mouseover/mouseout 状态。这部分效果很好,使用这种方法可以引发简单的笔触颜色变化
const Cursor = (props) =>
const hoverState = useSelector(state => state.gameState.targetHovered);
// ...
return (
<Crosshair isHovering=hoverState position=props.position>
<circle
cx=cursorCoordinates.cx
cy=cursorCoordinates.cy
r=cursorCoordinates.outerRadius
style=cursorStyle
/>
<circle
cx=cursorCoordinates.cx
cy=cursorCoordinates.cy
r=cursorCoordinates.innerRadius
style=cursorStyle
/>
<line
id="top"
x1=cursorCoordinates.cx - cursorCoordinates.outerRadius
y1=cursorCoordinates.cy
x2=cursorCoordinates.cx - cursorCoordinates.innerRadius
y2=cursorCoordinates.cy
style=crossHairStyle
/>
<line
id="bottom"
x1=cursorCoordinates.cx + cursorCoordinates.innerRadius
y1=cursorCoordinates.cy
x2=cursorCoordinates.cx + cursorCoordinates.outerRadius
y2=cursorCoordinates.cy
style=crossHairStyle
/>
</Crosshair>
);
以及样式化组件的代码...
const lockOn = (x, y) => keyframes`
0%
transform: rotate(0deg);
100%
transform: rotate(90deg);
`;
const Crosshair = styled.g`
transform-origin: $props => props.position.x $props => props.position.y;
animation: $props => props.isHovering ? lockOn : 'none' 1s linear;
`;
我尝试以多种不同的方式表达关键帧,但每次,当光标悬停在目标对象上时,动画不会旋转样式组组件中的元素,而是将其扔到正确的,好像变换原点不知何故不正确。从 Crosshair 中删除 transform-origin 表现出相同的行为
我确定我犯了一个简单的语法错误。有什么想法吗?
【问题讨论】:
想必你需要 transform-box: fill-box;如果这不起作用,请提供minimal reproducible example,即我们可以直接自己运行的东西。 @RobertLongson 是的,这就是解决方案。 styled.g 中只有 2 行代码(见下文) 【参考方案1】:正如@RobertLongson 在 cmets 中指出的那样,解决方案是添加
transform-box: fill-box;
在 styled.g 组件内,否则 transform-origin 是 SVG 对象的中心。有关 MDN 文档的更多详细信息,请点击此处:https://developer.mozilla.org/en-US/docs/Web/CSS/transform-box
添加转换原点也是必要的。注意动画中需要“向前”以防止在光标仍悬停在对象上时重置它
const lockOn = (x, y) => keyframes`
from
transform: rotate(0deg);
to
transform: rotate(90deg);
`;
const Crosshair = styled.g`
transform-origin: 50% 50%;
transform-box: fill-box;
animation: $props => props.isHovering ? lockOn : 'none' 0.3s linear forwards;
`;
【讨论】:
以上是关于动画 SVG 组对象 - 使用样式组件进行变换旋转不会围绕圆原点旋转的主要内容,如果未能解决你的问题,请参考以下文章