使用 Animated React Native Expo 缩放图像不会永久应用
Scale an image with Animated react native expo is not applying permanently
我正在尝试在用户按下时增加图像的大小,并在用户再次按下时使用以下动画 API 缩小图像:
const [viewState, setViewState]= useState(true);
const scaleAnim = (new Animated.Value(.9))
const scaleOut = () => {
if(viewState){
Animated.timing(scaleAnim, {
toValue: 2.2,
duration: 2000,
useNativeDriver:true,
}).start(()=>{setViewState(false)});
}
else{
Animated.timing(scaleAnim, {
toValue: .9,
duration: 700,
useNativeDriver:true,
}).start(setViewState(true));
}
};
<Animated.View style={{transform:[{scale:scaleAnim}]}} >
<Image style={styles.image} source={require('../path..')} />
</Animated.View>
const styles = StyleSheet.create({
image: {
width:70,
resizeMode:"contain",
height: 45,
alignSelf: "center",
},
但问题是,只要持续时间结束,尺寸就会恢复到默认值。我想永久保留并在用户再次按下时做相反的事情(减小尺寸)
有什么建议吗?
创建了一个组件希望这是你想要的....
小吃:https://snack.expo.io/neEtc2ihJ
export default function App() {
const [viewState, setViewState] = React.useState(true);
const scale = React.useRef(new Animated.Value(1)).current;
const [init, setInit] = React.useState(true);
React.useEffect(() => {
if (init) {
setInit(false);
} else {
if (viewState) {
Animated.timing(scale, {
toValue: 2,
duration: 1000,
useNativeDriver: true,
}).start();
} else {
Animated.timing(scale, {
toValue: 0.5,
duration: 700,
useNativeDriver: true,
}).start();
}
}
}, [viewState]);
const scaleOut = () => {
setViewState(!viewState);
};
return (
<View style={styles.container}>
<Animated.View style={{ transform: [{ scale }] }}>
<Image
style={styles.image}
source={require('./assets/snack-icon.png')}
/>
</Animated.View>
<Button title="animate" onPress={scaleOut} />
</View>
);
}
首先,您希望动画值为 useState
或 useRef
。 react-native 示例使用 useRef,所以我建议您也这样做。我还建议您使用插值来缩放,以便您可以将更多动画与该动画值相关联。结果将是这样的:
const animatedValue = useRef(new Animated.Value(0)).current;
const [ toggle, setToggle ] = useState(false)
const scaleOut = () => {
let animation
if(!toggle){
animation = Animated.timing(animatedValue, {
toValue: 1,
duration: 700,
useNativeDriver:true,
});
}
else{
animation = Animated.timing(animatedValue, {
toValue: 0,
duration: 2000,
useNativeDriver:true,
});
}
animation.start(()=>{
setToggle(!toggle)
})
};
let scaleAnim = animatedValue.interpolate({
inputRange:[0,1],
outputRange:[0.9,2.2]
})
return (
<Animated.View style={{transform:[{scale:scaleAnim}]}} >
<TouchableOpacity onPress={scaleOut}>
<Image style={styles.image} source={require('../path..')} />
</TouchableOpacity>
</Animated.View>
);
通过这样做,您可以通过添加另一个插值来将多张图像缩放为您想要的任何大小。但是,如果您不想这样做:
const scaleOut = () => {
let animation
if(!toggle){
animation = Animated.timing(animatedValue, {
toValue: 2.2,
duration: 2000,
useNativeDriver:true,
});
}
else{
animation = Animated.timing(animatedValue, {
toValue: 0.9,
duration: 700,
useNativeDriver:true,
});
}
animation.start(()=>{
setToggle(!toggle)
})
};
return (
<Animated.View style={{transform:[{scale:animatedValue}]}} >
<TouchableOpacity onPress={scaleOut} />
<Image style={styles.image} source={require('../path..')} />
</TouchableOpacity>
</Animated.View>
);
如果您想更进一步,将 TouchableOpacity 换成 Pressable,将动画放在 Animated.loop
中并在 onPressIn 中启动,在 pressOut 时停止动画并设置 animatedValue回到初始值:
const onPressIn= ()=>{
Animated.loop([
Animated.timing(animatedValue, {
toValue: 2.2,
duration: 2000,
useNativeDriver:true,
}),
Animated.timing(animatedValue, {
toValue: 0.9,
duration: 700,
useNativeDriver:true,
});
],{useNativeDriver:true}).start()
}
const onPressOut= ()=>{
animatedValue.stop()
Animated.timing(animatedValue,{
toValue: 0.9,
duration: 700,
useNativeDriver:true,
})
}
return(
<Pressable onPressIn={onPressIn} onPressOut={onPressOut}>
<Animated.View style={{transform:[{scale:animatedValue}]}} >
<Image style={styles.image} source={require('../path..')} />
</Animated.View>
</Pressable>
);
我正在尝试在用户按下时增加图像的大小,并在用户再次按下时使用以下动画 API 缩小图像:
const [viewState, setViewState]= useState(true);
const scaleAnim = (new Animated.Value(.9))
const scaleOut = () => {
if(viewState){
Animated.timing(scaleAnim, {
toValue: 2.2,
duration: 2000,
useNativeDriver:true,
}).start(()=>{setViewState(false)});
}
else{
Animated.timing(scaleAnim, {
toValue: .9,
duration: 700,
useNativeDriver:true,
}).start(setViewState(true));
}
};
<Animated.View style={{transform:[{scale:scaleAnim}]}} >
<Image style={styles.image} source={require('../path..')} />
</Animated.View>
const styles = StyleSheet.create({
image: {
width:70,
resizeMode:"contain",
height: 45,
alignSelf: "center",
},
但问题是,只要持续时间结束,尺寸就会恢复到默认值。我想永久保留并在用户再次按下时做相反的事情(减小尺寸)
有什么建议吗?
创建了一个组件希望这是你想要的....
小吃:https://snack.expo.io/neEtc2ihJ
export default function App() {
const [viewState, setViewState] = React.useState(true);
const scale = React.useRef(new Animated.Value(1)).current;
const [init, setInit] = React.useState(true);
React.useEffect(() => {
if (init) {
setInit(false);
} else {
if (viewState) {
Animated.timing(scale, {
toValue: 2,
duration: 1000,
useNativeDriver: true,
}).start();
} else {
Animated.timing(scale, {
toValue: 0.5,
duration: 700,
useNativeDriver: true,
}).start();
}
}
}, [viewState]);
const scaleOut = () => {
setViewState(!viewState);
};
return (
<View style={styles.container}>
<Animated.View style={{ transform: [{ scale }] }}>
<Image
style={styles.image}
source={require('./assets/snack-icon.png')}
/>
</Animated.View>
<Button title="animate" onPress={scaleOut} />
</View>
);
}
首先,您希望动画值为 useState
或 useRef
。 react-native 示例使用 useRef,所以我建议您也这样做。我还建议您使用插值来缩放,以便您可以将更多动画与该动画值相关联。结果将是这样的:
const animatedValue = useRef(new Animated.Value(0)).current;
const [ toggle, setToggle ] = useState(false)
const scaleOut = () => {
let animation
if(!toggle){
animation = Animated.timing(animatedValue, {
toValue: 1,
duration: 700,
useNativeDriver:true,
});
}
else{
animation = Animated.timing(animatedValue, {
toValue: 0,
duration: 2000,
useNativeDriver:true,
});
}
animation.start(()=>{
setToggle(!toggle)
})
};
let scaleAnim = animatedValue.interpolate({
inputRange:[0,1],
outputRange:[0.9,2.2]
})
return (
<Animated.View style={{transform:[{scale:scaleAnim}]}} >
<TouchableOpacity onPress={scaleOut}>
<Image style={styles.image} source={require('../path..')} />
</TouchableOpacity>
</Animated.View>
);
通过这样做,您可以通过添加另一个插值来将多张图像缩放为您想要的任何大小。但是,如果您不想这样做:
const scaleOut = () => {
let animation
if(!toggle){
animation = Animated.timing(animatedValue, {
toValue: 2.2,
duration: 2000,
useNativeDriver:true,
});
}
else{
animation = Animated.timing(animatedValue, {
toValue: 0.9,
duration: 700,
useNativeDriver:true,
});
}
animation.start(()=>{
setToggle(!toggle)
})
};
return (
<Animated.View style={{transform:[{scale:animatedValue}]}} >
<TouchableOpacity onPress={scaleOut} />
<Image style={styles.image} source={require('../path..')} />
</TouchableOpacity>
</Animated.View>
);
如果您想更进一步,将 TouchableOpacity 换成 Pressable,将动画放在 Animated.loop
中并在 onPressIn 中启动,在 pressOut 时停止动画并设置 animatedValue回到初始值:
const onPressIn= ()=>{
Animated.loop([
Animated.timing(animatedValue, {
toValue: 2.2,
duration: 2000,
useNativeDriver:true,
}),
Animated.timing(animatedValue, {
toValue: 0.9,
duration: 700,
useNativeDriver:true,
});
],{useNativeDriver:true}).start()
}
const onPressOut= ()=>{
animatedValue.stop()
Animated.timing(animatedValue,{
toValue: 0.9,
duration: 700,
useNativeDriver:true,
})
}
return(
<Pressable onPressIn={onPressIn} onPressOut={onPressOut}>
<Animated.View style={{transform:[{scale:animatedValue}]}} >
<Image style={styles.image} source={require('../path..')} />
</Animated.View>
</Pressable>
);