Open
Description
Bug
Animating strokeDashoffset
of a path does not work on IOS but works on Android. It works if the value of strokeDashoffset
and strokeDasharray
do not switch between undefined
and the actual value I want. However in my case I want to know the length of the path and use that to animate the path, so when the path length is unknown I assign strokeDasharray
and ..offset
to undefined
Unexpected behavior
The unexpected behavior is that ios does not animate when it should.
Environment info
React native info output:
System:
OS: macOS 14.1.2
CPU: (16) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
Memory: 1.59 GB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 18.17.1
path: ~/.nvm/versions/node/v18.17.1/bin/node
Yarn:
version: 1.22.19
path: ~/.nvm/versions/node/v18.17.1/bin/yarn
npm:
version: 9.6.7
path: ~/.nvm/versions/node/v18.17.1/bin/npm
Watchman:
version: 2023.10.09.00
path: /usr/local/bin/watchman
Managers:
CocoaPods:
version: 1.14.2
path: /Users/ramiel/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 23.2
- iOS 17.2
- macOS 14.2
- tvOS 17.2
- watchOS 10.2
Android SDK: Not Found
IDEs:
Android Studio: 2023.1 AI-231.9392.1.2311.11076708
Xcode:
version: 15.1/15C65
path: /usr/bin/xcodebuild
Languages:
Java:
version: 11.0.15
path: /usr/local/opt/openjdk@11/bin/javac
Ruby:
version: 2.7.6
path: /Users/ramiel/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 18.2.0
wanted: 18.2.0
react-native:
installed: 0.73.1
wanted: 0.73.1
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: false
iOS:
hermesEnabled: true
newArchEnabled: false
Library version: 14.1.0
Steps To Reproduce
- git clone https://github.com/itsramiel/svg-path-animation-repro
- cd svg-path-animation-repro
- yarn
- yarn ios
- notice that path doesnt animate
- yarn android
- notice that path animate
Describe what you expected to happen:
- I expect ios to work like android and the path animated
Short, Self Contained, Correct (Compilable), Example
import Animated, {
useAnimatedProps,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import {useEffect, useRef, useState} from 'react';
import {View} from 'react-native';
import {Path, Svg} from 'react-native-svg';
const WIDTH = 200;
const HEIGHT = 100;
const d = 'M 0 50 L 10 50 L 15 70 L 40 130 L 150 20';
const AnimatedPath = Animated.createAnimatedComponent(Path);
function App() {
const progress = useSharedValue(1);
const ref = useRef<Path>(null);
const [pathLength, setPathLength] = useState<null | number>(null);
useEffect(() => {
const res = ref.current?.getTotalLength();
if (typeof res === 'number') {
setPathLength(res);
}
}, []);
useEffect(() => {
if (typeof pathLength === 'number') {
progress.value = withTiming(0, {duration: 3000});
}
}, [pathLength]);
const animatedProps = useAnimatedProps(() => {
return {
strokeDashoffset: pathLength === null ? 0 : progress.value * pathLength,
};
}, [pathLength]);
return (
<View style={{flex: 1, justifyContent: 'center'}}>
<Svg style={{width: '100%', aspectRatio: WIDTH / HEIGHT}}>
<AnimatedPath
ref={ref}
d={d}
stroke={pathLength === null ? 'none' : 'black'}
fill={'none'}
strokeWidth={2}
strokeDasharray={pathLength ?? undefined}
animatedProps={animatedProps}
/>
</Svg>
</View>
);
}
export default App;