React Native SVG动态两点间路径绘制动画实现问题
解决动态两点间SVG路径绘制动画问题
核心问题是你之前用固定值设置strokeDasharray,但路径长度随两点位置动态变化,导致动画无法适配所有情况。下面是修正后的方案:
关键思路
利用勾股定理计算当前路径的实际长度,将strokeDasharray设置为路径总长度(让整个路径成为一个完整的“虚线段”),再通过strokeDashoffset从总长度插值到0,实现从起点到终点的绘制动画。
修正后的完整代码
import { useState, useEffect } from 'react'; import { View } from 'react-native'; import Svg, { Path } from 'react-native-svg'; import Animated, { useSharedValue, withTiming, useAnimatedProps, interpolate, Easing } from 'react-native-reanimated'; const AnimatedPath = Animated.createAnimatedComponent(Path); export default function YourComponent() { const [pointAPixels, setPointAPixels] = useState({ x: 0, y: 0 }); const [pointBPixels, setPointBPixels] = useState({ x: 0, y: 0 }); const animationProgress = useSharedValue(0); // 当两点位置变化时,重置并启动2秒时长的动画 useEffect(() => { animationProgress.value = 0; animationProgress.value = withTiming(1, { duration: 2000, easing: Easing.linear, }); }, [pointAPixels, pointBPixels]); const animatedProps = useAnimatedProps(() => { // 计算两点间直线的实际长度(路径总长度) const pathLength = Math.hypot( pointBPixels.x - pointAPixels.x, pointBPixels.y - pointAPixels.y ); // 插值:从路径总长度降到0,实现从起点到终点的绘制效果 const dashOffset = interpolate(animationProgress.value, [0, 1], [pathLength, 0]); return { strokeDasharray: `${pathLength}`, // 虚线段长度等于路径总长度 strokeDashoffset: dashOffset, }; }); return ( <View> <Svg width={320} height={320}> <SvgFrance width={320} height={320} fill="black" /> <AnimatedPath d={`M ${pointAPixels.x} ${pointAPixels.y} L ${pointBPixels.x} ${pointBPixels.y}`} stroke="black" strokeWidth="2" animatedProps={animatedProps} /> </Svg> </View> ); }
代码说明
- 路径长度计算:用
Math.hypot计算两点x、y坐标差的斜边长度,得到直线路径的准确长度,适配任意位置的两点。 - 动画逻辑:
strokeDasharray设为路径总长度,意味着整个路径是一个单独的虚线段;strokeDashoffset从总长度变为0时,相当于这个虚线段从起点位置逐渐“移动”到终点,视觉上就是路径被逐步绘制出来。 - 依赖修正:将
useEffect的依赖改为pointAPixels和pointBPixels,确保每次两点位置变化时都能重新计算路径长度并启动动画。
内容的提问来源于stack exchange,提问作者yannou974
相关产品推荐
相关产品推荐

