Skip to content

Commit ad9d502

Browse files
committed
Fix connection of AnimatedNodes and creation of redundant AnimatedNodes
When using one AnimatedValue to interpolate several properties in one View, it caused several redundant AnimatedNodes to be created for the same AnimatedProps. Additionally, the connections to the AnimatedProps were made before the native node for the AnimatedProps was created, causing them not to work. This splits the connection creation out from the makeNative call, and calls it after all the required nodes are created. Test App.js: ```jsx import React, { Component } from 'react'; import { StyleSheet, View, Dimensions, Animated } from 'react-native'; import { Svg, Rect, Path } from 'react-native-svg'; const { width, height } = Dimensions.get('window'); const AnimatedRect = Animated.createAnimatedComponent(Rect); const AnimatedPath = Animated.createAnimatedComponent(Path); function getInitialState() { const anim = new Animated.Value(0); const fillOpacity = anim.interpolate({ inputRange: [0, 1], outputRange: [0, 1], }); const offset = anim.interpolate({ inputRange: [0, 1], outputRange: [0, 10], }); const strokeOpacity = anim.interpolate({ inputRange: [0, 1], outputRange: [0, 1], extrapolateRight: 'clamp', }); const path = anim.interpolate({ inputRange: [0, 1], outputRange: ['M20,20L20,80L80,80L80,20Z', 'M40,40L33,60L60,60L65,40Z'], }); const fill = anim.interpolate({ inputRange: [0, 1], outputRange: ['rgba(255, 0, 0, 0.5)', 'rgba(0, 255, 0, 0.99)'], }); const oneToFivePx = anim.interpolate({ inputRange: [0, 1], outputRange: ['1px', '5px'], }); return { anim, fillOpacity, offset, strokeOpacity, path, fill, oneToFivePx }; } export default class App extends Component { state = getInitialState(); componentDidMount() { const { anim } = this.state; Animated.timing(anim, { toValue: 1, duration: 10000, useNativeDriver: true, }).start(); } render() { const { fillOpacity, offset, strokeOpacity, path, fill, oneToFivePx } = this.state; return ( <View style={styles.container}> <Svg width={width} height={height} viewBox="0 0 100 100"> <AnimatedRect x="5" y="5" width="90" height="90" stroke="blue" fill={fill} strokeDasharray="1 1" strokeWidth={oneToFivePx} strokeDashoffset={offset} strokeOpacity={strokeOpacity} fillOpacity={fillOpacity} /> <AnimatedPath d={path} stroke="blue" /> </Svg> </View> ); } } const styles = StyleSheet.create({ container: { backgroundColor: '#ecf0f1', }, }); ```
1 parent 588fa26 commit ad9d502

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

Libraries/Animated/src/animations/Animation.js

+1
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ class Animation {
5757
}
5858
__startNativeAnimation(animatedValue: AnimatedValue): void {
5959
animatedValue.__makeNative();
60+
animatedValue.__connectAnimatedNodes();
6061
this.__nativeId = NativeAnimatedHelper.generateNewAnimationId();
6162
NativeAnimatedHelper.API.startAnimatingNode(
6263
this.__nativeId,

Libraries/Animated/src/nodes/AnimatedNode.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,18 @@ class AnimatedNode {
3535

3636
/* Methods and props used by native Animated impl */
3737
__isNative: boolean;
38+
__isConnected: boolean;
3839
__nativeTag: ?number;
3940
__makeNative() {
4041
if (!this.__isNative) {
4142
throw new Error('This node cannot be made a "native" animated node');
4243
}
4344
}
45+
__connectAnimatedNodes() {
46+
if (!this.__isNative) {
47+
throw new Error('This node cannot be connected natively');
48+
}
49+
}
4450
__getNativeTag(): ?number {
4551
NativeAnimatedHelper.assertNativeAnimatedModule();
4652
invariant(
@@ -49,11 +55,11 @@ class AnimatedNode {
4955
);
5056
if (this.__nativeTag == null) {
5157
const nativeTag: ?number = NativeAnimatedHelper.generateNewNodeTag();
58+
this.__nativeTag = nativeTag;
5259
NativeAnimatedHelper.API.createAnimatedNode(
5360
nativeTag,
5461
this.__getNativeConfig(),
5562
);
56-
this.__nativeTag = nativeTag;
5763
}
5864
return this.__nativeTag;
5965
}

Libraries/Animated/src/nodes/AnimatedWithChildren.js

+9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,15 @@ class AnimatedWithChildren extends AnimatedNode {
2525
this.__isNative = true;
2626
for (const child of this._children) {
2727
child.__makeNative();
28+
}
29+
}
30+
}
31+
32+
__connectAnimatedNodes() {
33+
if (!this.__isConnected) {
34+
this.__isConnected = true;
35+
for (const child of this._children) {
36+
child.__connectAnimatedNodes();
2837
NativeAnimatedHelper.API.connectAnimatedNodes(
2938
this.__getNativeTag(),
3039
child.__getNativeTag(),

0 commit comments

Comments
 (0)