react-native-reanimated
react-native-reanimated copied to clipboard
Animated props do not work on images on IOS
Discussed in https://github.com/software-mansion/react-native-reanimated/discussions/2973
Originally posted by maidul98 February 8, 2022 When i updated the shared value holding an URI to an image, the update doesn't change the image.
const sharedHeaderSize = useSharedValue(185);
const img = useSharedValue("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png");
const props = useAnimatedProps(()=>{
return {
source: {uri: img.value}
}
}, [img])
return (
<View style={{marginTop: 100}}>
<TouchableOpacity onPress={() => img.value = "https://www.pngkit.com/png/full/119-1198978_mono-sound-wave-waveform-track.png"}><Text>Click here</Text></TouchableOpacity>
<Animated.Image animatedProps={props} style={{height: 120, width: "100%"}}/>
</View>
);
When you click the text, it updates the shared value but the prop doesn't update so the image stays the same Issue reproduced here: https://snack.expo.dev/@maidul98/reanimated-2
Hey! 👋
It looks like you've omitted a few important sections from the issue template.
Please complete Description, Snack or minimal code example, Package versions and Affected platforms sections.
I have checked below code (changed maidui98's code), works correctly on android(expo-go) but doesn't work on web(snack).
import React, { useEffect } from 'react';
import {
Text,
View,
StyleSheet,
ScrollView,
TouchableOpacity,
Button,
} from 'react-native';
import Animated, {
useSharedValue,
useAnimatedStyle,
withTiming,
useAnimatedScrollHandler,
withSpring,
useAnimatedProps,
} from 'react-native-reanimated';
export default function App() {
const sharedHeaderSize = useSharedValue(10);
const img = useSharedValue(
'https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png'
);
const [a, setA] = React.useState(0);
// useEffect(()=>{
// transY.value = "dwddwddeef d"
// console.log(transY)
// }, [])
const props = useAnimatedProps(() => {
return {
source: { uri: img.value },
};
});
const style = useAnimatedStyle(() => {
return {
height: sharedHeaderSize.value,
width: sharedHeaderSize.value
};
});
return (
<View style={{ marginTop: 100 }}>
<TouchableOpacity
onPress={() =>
(img.value =
'https://www.pngkit.com/png/full/119-1198978_mono-sound-wave-waveform-track.png')
}>
<Text>HELLO</Text>
</TouchableOpacity>
<Button
onPress={() => {
sharedHeaderSize.value = 200;
}}
title="hoge"
/>
<Animated.Image
animatedProps={props}
style={[{ width: '100%' }, style]}
/>
</View>
);
}
Yeah bug exists on IOS, not sure why
I don't think there's a reason for using this package for updating image sources. Try using useState with a boolean and give the URL conditionally. That way react should know when to re-render your image component.
@coneforapine it is still a valid question that I would like to know the answer to. Maybe they are building an video frame scrubber that needs to update images quickly
This is is still happening when you animate the blurRadius prop
Same error over here on iOS device
My versions:
"react-native": "0.69.1",
"react-native-reanimated": "^2.9.1",
My code:
import React, { FC } from 'react';
import { Image } from 'react-native';
import Animated, { useAnimatedProps } from 'react-native-reanimated';
import styles from './styles';
const AnimatedImage = Animated.createAnimatedComponent(Image);
Animated.addWhitelistedNativeProps({ source: true });
type Props = { sharedValue: Animated.SharedValue<string> };
const CameraOverlayView: FC<Props> = ({ sharedValue }) => {
const props = useAnimatedProps(() => {
return {
source: sharedValue.value ? { uri: sharedValue.value } : undefined,
};
}, [sharedValue.value]);
return <AnimatedImage style={styles.cameraOverlay} animatedProps={props} />;
};
export default CameraOverlayView;
Error converting JSON Value '{ uri = "data:image/png;base64,(myBase64Data)" }'
on "RCTConvert.m 57 [RCTConvert NSArray]
I solved this with a library I made for images: https://github.com/candlefinance/faster-image
const AnimatedImage = Animated.createAnimatedComponent(FasterImageView)
const animatedProps = useAnimatedProps(() => {
return {
url: image.value,
}
})