When doing a withTiming color animation on web with less than 250 in duration and a scale withSpring animation it reverts to first color on completion
Using interpolateColor function from react-native-reanimated but tested with the one from react-native-redash and same issue
Web example with error

working example on emulator

Row should turn green in web
Row goes back to background color
here below is the component getting set active on press. Removed other animations for simplicty
export const EmojiButton = ({active, onPress}) => {
const theme = useTheme();
const color = useSharedValue(0);
const scale = useSharedValue(1);
useEffect(() => {
if (active) {
color.value = withTiming(2, {duration: 249, easing: Easing.linear});
scale.value = withSpring(1.2, {stiffness: 400, damping: 10});
} else {
color.value = 0;
scale.value = 1;
}
}, [active]);
const animationStyles = useAnimatedStyle(() => {
return {
backgroundColor: interpolateColor(
color.value,
[0, 1, 2],
[theme.backgroundColor, theme.buttonPressedColor, theme.primaryColor],
),
transform: [
{
scaleY: scale.value,
},
],
};
}, [theme]);
return (
<Pressable onPress={onPress}>
<Animated.View
style={[
{
height: 80,
borderBottomColor: theme.dividerColor,
borderBottomWidth: 1,
},
animationStyles,
]}
/>
</Pressable>
);
};
Hey @gust42
I tried to reproduce your issue but it works for me. Could you check if this code below does work for you?

code
import Animated, {
useSharedValue,
withTiming,
useAnimatedStyle,
Easing,
interpolateColor,
withSpring
} from 'react-native-reanimated';
import { View, Button } from 'react-native';
import React, {useState} from 'react';
export default function AnimatedStyleUpdateExample(props) {
const [active, setActive] = useState(true)
return (
<View>
<Button
title="toggle"
onPress={() => setActive(!active)}
/>
<EmojiButton active={active} onPress={console.log} />
</View>
);
}
export const EmojiButton = ({active, onPress}) => {
// const theme = useTheme();
const color = useSharedValue(0);
const scale = useSharedValue(1);
React.useEffect(() => {
if (active) {
color.value = withTiming(2, {duration: 249, easing: Easing.linear});
scale.value = withSpring(1.2, {stiffness: 400, damping: 10});
} else {
color.value = 0;
scale.value = 1;
}
}, [active]);
const animationStyles = useAnimatedStyle(() => {
return {
backgroundColor: interpolateColor(
color.value,
[0, 1, 2],
['#ff0000', '#00ff00', '#0000ff'],
),
transform: [
{
scaleY: scale.value,
},
],
};
}, []);
return (
<View onPress={onPress}>
<Animated.View
style={[
{
marginTop: 10,
height: 80,
borderBottomColor: '#ffffff',
borderBottomWidth: 1,
},
animationStyles,
]}
/>
</View>
);
};
Can you try with a lower duration on the color timing aswell? I have found that its not exacly tied to 250ms
just for certainty - Do you also have this issue when you run my example code?
Not initially but when i lowererd duration on this line
color.value = withTiming(2, {duration: 249, easing: Easing.linear});
to around 200, but behaves really weird because when i turned it back up it didnt work until around 280ms, same thing in incoqnito window aswell
I found this issue and I鈥檓 working on it. If you need fast fix since we fix this issue, downgrade react-native-web to version 0.12.3
Excellent! Thanks for the help 馃憤
Yeah, this one affects me too.
Most helpful comment
The issue is the effect of changes in
react-native-web0.13. The RNW team removedforwardedRefprops. 馃様We wait for patch and stay with version 0.12. More information here and here