我正在尝试在React-Native (React-Native -svg)中创建svg图标的脉动效果。我对Reanimated的动画效果很满意。我正在考虑通过改变路径的"尺度"值来创造脉动效果。问题是,修改"比例"值要么"切断"图像的可见部分,如果比例值为>1或值小于1时,它会缩小移动到一边(即。不在视线中心。我理解svg将左上角作为原点。
const AnimatedPath = Animated.createAnimatedComponent(Path);
const PulsatingSign = () => {
return (
<Svg width={43} height={63} viewBox="0 0 43 63" fill="red">
<AnimatedPath scale={animatedValue} d="M......" />
</Svg>
);
};
我唯一能想到的是动画(即:改变值)width
和height
:
const PulsatingSign = () => {
return (
<Svg width={animatedWidth} height={animatedHeight} viewBox={`0 0 ${animatedWidth} ${animatedHeight}`} fill="red">
<Path d="M......" />
</Svg>
);
};
或者用View包装svg组件并缩放View(我的假设是直接动画svg元素会更高效,而不是包装视图。
const PulsatingSign = () => {
return (
<Animated.View style={{ transform: [{ scale: animatedValue }]}>
<Svg width="100%" height="100%" viewBox="0 0 43 67" fill="red">
<Path d="M......" />
</Svg>
</Animated.View>
);
};
让图标保持在正中间并保持脉动的最好方法是什么?重新调节)。
有两个问题:
- 路径的0,0点位于路径的某个位置,而不是中间位置。
- 缩放使路径比viewBox大。
在不改变路径的情况下(你也可以通过将0,0点移动到路径的中间来改变路径),你可以将父组元素动画化,同时变换/翻译路径,使0,0点最终位于路径的中间。
与其将路径向上缩放,这样对于viewBox来说它就会变得太大,不如将路径向下缩放。另一种方法是使viewBox变大,或者编辑路径使其变小。
svg {
display: block;
}
<p>Plain SVG path</p>
<svg width="43" height="63" viewBox="0 0 43 63" fill="red">
<path d="M 2 2 L 21 5 L 41 2 L 36 29 L 41 60 L 21 55 L 2 60 L 7 29 Z" />
</svg>
<p>Issue: scales from 0,0 and is too big</p>
<svg width="43" height="63" viewBox="0 0 43 63" fill="red">
<path d="M 2 2 L 21 5 L 41 2 L 36 29 L 41 60 L 21 55 L 2 60 L 7 29 Z">
<animateTransform
attributeName="transform"
attributeType="XML"
type="scale"
values="1; 1.5; 1"
dur="2s"
repeatCount="indefinite" />
</path>
</svg>
<p>Issue: is too big</p>
<svg width="43" height="63" viewBox="0 0 43 63" fill="red">
<g transform="translate(22 30)">
<g>
<animateTransform
attributeName="transform"
attributeType="XML"
type="scale"
values="1; 1.5; 1"
dur="2s"
repeatCount="indefinite" />
<path transform="translate(-22 -30)"
d="M 2 2 L 21 5 L 41 2 L 36 29 L 41 60 L 21 55 L 2 60 L 7 29 Z"/>
</g>
</g>
</svg>
<p>No issues</p>
<svg width="43" height="63" viewBox="0 0 43 63" fill="red">
<g transform="translate(22 30)">
<g>
<animateTransform
attributeName="transform"
attributeType="XML"
type="scale"
values="1; .8; 1"
dur="2s"
repeatCount="indefinite" />
<path transform="translate(-22 -30)"
d="M 2 2 L 21 5 L 41 2 L 36 29 L 41 60 L 21 55 L 2 60 L 7 29 Z"/>
</g>
</g>
</svg>