I want to shake the below View when my password is wrong.
for example:
it should be translateX from place 10, to place 20 for 4 time and 1 second.
then should be stopped in place 10.
place 10 (I mean the X position of View)
startShake = () => {
Animated.loop(
Animated.sequence([
Animated.timing(this.animatedValue, {toValue: 1, duration: 150, easing: Easing.linear, useNativeDriver: true}),
Animated.timing(this.animatedValue, {toValue: -1, duration: 300, easing: Easing.linear, useNativeDriver: true}),
Animated.timing(this.animatedValue, {toValue: 0, duration: 150, easing: Easing.linear, useNativeDriver: true}),
])
).start();
}
<Animated.View style={{transform: [{
translateX: this.animatedValue.interpolate({
inputRange: [0, 0],
outputRange: [0, 0]
})
}]
}}>
</Animated.View>
Thank you for all answers.
I just solved editing my code with the following code
constructor(props) {
super(props)
this.shakeAnimation = new Animated.Value(0);
}
startShake = () => {
Animated.sequence([
Animated.timing(this.shakeAnimation, { toValue: 10, duration: 100, useNativeDriver: true }),
Animated.timing(this.shakeAnimation, { toValue: -10, duration: 100, useNativeDriver: true }),
Animated.timing(this.shakeAnimation, { toValue: 10, duration: 100, useNativeDriver: true }),
Animated.timing(this.shakeAnimation, { toValue: 0, duration: 100, useNativeDriver: true })
]).start();
}
<Animated.View style={{ transform: [{translateX: this.shakeAnimation}] }}>
</Animated.View>
Here is the shake animation for Image component in react native, you can check it-
const bgImage = require('./components/images/ex.jpg')
class App extends Component {
constructor(props) {
super(props)
this.animatedValue = new Animated.Value(0)
}
handleAnimation = () => {
// A loop is needed for continuous animation
Animated.loop(
// Animation consists of a sequence of steps
Animated.sequence([
// start rotation in one direction (only half the time is needed)
Animated.timing(this.animatedValue, {toValue: 1.0, duration: 150, easing: Easing.linear, useNativeDriver: true}),
// rotate in other direction, to minimum value (= twice the duration of above)
Animated.timing(this.animatedValue, {toValue: -1.0, duration: 300, easing: Easing.linear, useNativeDriver: true}),
// return to begin position
Animated.timing(this.animatedValue, {toValue: 0.0, duration: 150, easing: Easing.linear, useNativeDriver: true})
])
).start();
}
}
To add this Animation to Image Component-
<Animated.Image
source={bgImage}
resizeMode='contain'
style={{
transform: [{
rotate: this.animatedValue.interpolate({
inputRange: [-1, 1],
outputRange: ['-0.1rad', '0.1rad']
})
}]
}}
/>
There is a library : react-native-animitable
You can do wonders using this library and is really very easy to use with least codes.
You can do this without loop.
startShake = () => {
this.animatedValue.setValue(0);
Animated.timing(this.animatedValue,
{
toValue: 1,
duration: 150,
easing: Easing.linear,
useNativeDriver: true
}
).start()
}
<Animated.View style={{transform: [{
translateX: this.animatedValue.interpolate({
inputRange: [0, 0.25, 0.50, 0.75, 1],
outputRange: [10, 20, 10, 20, 10]
})
}]
}}>
</Animated.View>
It might some help you to get your required animation
class App extends Component {
constructor(props) {
super(props)
this.animatedValue = new Animated.Value(0)
}
handleAnimation = () => {
// A loop is needed for continuous animation
Animated.loop(
// Animation consists of a sequence of steps
Animated.sequence([
// start rotation in one direction (only half the time is needed)
Animated.timing(this.animatedValue, {toValue: 1.0, duration: 150, easing: Easing.linear, useNativeDriver: true}),
// rotate in other direction, to minimum value (= twice the duration of above)
Animated.timing(this.animatedValue, {toValue: -1.0, duration: 300, easing: Easing.linear, useNativeDriver: true}),
// return to begin position
Animated.timing(this.animatedValue, {toValue: 0.0, duration: 150, easing: Easing.linear, useNativeDriver: true})
])
).start();
}
}
<Animated.View
style={{
transform: [{
rotate: this.animatedValue.interpolate({
inputRange: [-1, 1],
outputRange: ['-0.1rad', '0.1rad']
})
}]
}}
/>
It can be a good solution with two axes:
import React, { useState } from "react";
import { StyleSheet, View, Animated, TouchableWithoutFeedback, Easing } from "react-native";
const Shake = () => {
const [animation] = useState(new Animated.Value(0));
const startAnimation = () => {
animation.setValue(0);
Animated.timing(animation, {
toValue: 1,
duration: 1500,
easing: Easing.linear,
useNativeDriver: true
}).start(()=>{
animation.setValue(0)
});
}
const animatedStyles = {
transform: [
{
translateX: animation.interpolate({
inputRange: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
outputRange: [0, 10, -10, 10, -10, 0, 0, 0, 0, 0, 0]
})
},
{
translateY: animation.interpolate({
inputRange: [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
outputRange: [0, 0, 0, 0, 0, 0, 10, -10, 10, -10, 0]
})
}
]
}
return <View style={styles.container}>
<TouchableWithoutFeedback onPress={startAnimation}>
<Animated.View style={[styles.box, animatedStyles]} />
</TouchableWithoutFeedback>
</View>
}
const styles = StyleSheet.create({
container: {
flex: 1,
height: 600,
alignItems: "center",
justifyContent: "center",
},
box: {
backgroundColor: "tomato",
width:150,
height:150
}
});
export default Shake
// #flow
import React, { useCallback, useEffect, useRef } from 'react'
import { Image, Animated } from 'react-native'
// Constants
const DEFAULT_STEP_TIME = 1000
interface Props {
source: string | number;
intensity?: number;
stepTime?: number;
iterations?: number;
containerStyle?: any;
style?: any;
}
const ShakingIcon = ({
source,
intensity = 2,
stepTime,
iterations = 2,
containerStyle,
style,
}: Props) => {
const interval = useRef(null)
const animation = useRef(new Animated.Value(0))
const shakeAnimation = useCallback(() => {
Animated.loop(
Animated.sequence([
Animated.timing(animation.current, {
toValue: -intensity,
duration: 50,
useNativeDriver: true,
}),
Animated.timing(animation.current, {
toValue: intensity,
duration: 50,
useNativeDriver: true,
}),
Animated.timing(animation.current, {
toValue: 0,
duration: 50,
useNativeDriver: true,
}),
]),
{ iterations },
).start()
}, [])
const runAnimation = useCallback(async () => {
interval.current = setInterval(
() => shakeAnimation(),
stepTime || DEFAULT_STEP_TIME,
)
}, [])
useEffect(() => {
runAnimation()
return () => clearInterval(interval.current)
}, [])
return (
<Animated.View
style={[
containerStyle,
{ transform: [{ translateX: animation.current }] },
]}
>
<Image source={source} style={style} />
</Animated.View>
)
}
export default ShakingIcon
based on https://snack.expo.dev/embedded/#ananthu.kanive/shake?iframeId=t099o2svbu&preview=true&platform=web&theme=light
Related
I have that code :
export default function Shimmer() {
const AnimatedView = Animated.createAnimatedComponent(LinearGradient);
const animatedValue = new Animated.Value(0);
const translateX = animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [-width, width],
});
useEffect(() => {
Animated.loop(
Animated.timing(
(animatedValue,
{
toValue: 1,
duration: 1000,
easing: Easing.linear,
useNativeDriver: true,
})
)
).start();
});
return (
<View style={styles.container}>
<View style={styles.backgroundView}>
<AnimatedView
colors={["#a0a0a0", "#b0b0b0", "#b0b0b0", "#a0a0a0"]}
start={{ x: 0, y: 0 }}
end={{ x: 1, y: 1 }}
style={[
StyleSheet.absoluteFillObject,
{
transform: [{ translateX: translateX }],
},
]}
/>
</View>
</View>
);
}
I would like to make a shimmer effect like shown in this video :
https://www.youtube.com/watch?v=PPwa0WMAH8A
I have set useNativeDriver to true, but I get this error :
Cannot read properties of undefined (reading 'useNativeDriver')
How can I fix that (I am working with Expo) ?
Problem solved by removing a parenthesis here :
Animated.loop(
Animated.timing(
animatedValue,
{
toValue: 1,
duration: 1000,
easing: Easing.linear,
useNativeDriver: true,
}
)
).start();
});
Animation in off the screen when it receives a positive value
Why it goes off-screen
For it to stay on screen I have to give it a negative value (e.g. -30)
const animation = useRef(new Animated.Value(0)).current;
const left = animation.interpolate({
inputRange: [0, 1],
outputRange: [0, 30],
});
const onClick = () => {
Animated.timing(animation, {
toValue: 30,
duration: 1000,
useNativeDriver: true,
}).start();
};
return (
<>
<View>
<Animated.View
style={{
backgroundColor: "red",
width: 100,
height: 100,
transform: [{ translateX: left }],
margin: 20,
}}
/>
</View>
</>
);
export default App;
const onClick = () => {
Animated.timing(animation, {
toValue: 1, //CHANGE THIS TO ONE IN YOUR CODE
duration: 1000,
useNativeDriver: true,
}).start();
};
you are interpolating on a value which goes to 30! but your input is 0,to 1!
i hope it helps
Thanks in advance for the help.
Attempting to have an image asset (in this case "yes.png") trigger two animations on touch ("onPress).
The image itself should spring (animated.spring) and then previously hidden text should appear.
Whatever I try I can only get it to do one or the other but not both.
Tried wrap both animations in a parallel aka
_springAnimation = () =>
Animated.parallel([
Animated.spring(this.state.springValue, {
toValue: 1.33,
friction: 0.47,
useNativeDriver: true,
}),
Animated.timing(this.state.fadeValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start(),
]);
and add <TouchableOpacity onPress={this._start}> after the first.
Here is the current code I have:
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
springValue: new Animated.Value(0.47),
useNativeDriver: true,
fadeValue: new Animated.Value(0),
};
}
_springAnimation = () => {
Animated.spring(this.state.springValue, {
toValue: 1.33,
friction: 0.47,
useNativeDriver: true,
}).start();
};
_start = () => {
Animated.timing(this.state.fadeValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
};
render() {
return (
<View style={styles.container}>
<TouchableOpacity onPress={this._springAnimation}>
<Animated.Image
source={require('animation/assets/yes.png')}
style={[
styles.imageView,
{
transform: [{scale: this.state.springValue}],
},
]}
/>
<Animated.View
style={{
opacity: this.state.fadeValue,
height: 60,
width: 200,
backgroundColor: 'black',
justifyContent: 'center',
}}>
<Text style={styles.buttonText}>Win</Text>
</Animated.View>
</TouchableOpacity>
</View>
);
}
}
If you want to run animation one after another. You can do this by Animated.sequence.
Animated.sequence([
Animated.spring(this.state.springValue, {
toValue: 1.33,
friction: 0.47,
useNativeDriver: true,
}),
Animated.timing(this.state.fadeValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
})
]).start(); // start the sequence group
They will start stop accordingly.
And If you want to run it parallel then try below code.
Animated.parallel([
Animated.spring(this.state.springValue, {
toValue: 1.33,
friction: 0.47,
useNativeDriver: true,
}),
Animated.timing(this.state.fadeValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
})
]).start(); // start the sequence group
I'm animating the TextInput to move with translateY, but when I apply the React Native animated, TextInput responds to typing only one character at a time. What I mean is, once a character has been input, the keyboard is dismissed.
I have three animations happening and others are working fine:
const [textInputAnimation] = useState(new Animated.Value(0))
useEffect(() => {
Animated.parallel([
Animated.timing(animation, {
toValue: 1,
duration: 800,
useNativeDriver: true,
}),
Animated.timing(textInputAnimation, {
toValue: 1,
duration: 400,
delay: 700,
useNativeDriver: true,
}),
Animated.timing(logoAnimation, {
toValue: 1,
duration: 400,
delay: 900,
useNativeDriver: true,
})
]).start()
}, [])
const translateYInterpolate = textInputAnimation.interpolate({
inputRange: [0, 1],
outputRange: [-50, 0]
})
const animatedOpacity = textInputAnimation.interpolate({
inputRange: [0, 1],
outputRange: [0, 1]
})
const animatedTranslateStyle = {
transform: [
{
translateY: translateYInterpolate
}
],
opacity: animatedOpacity,
}
const AnimatedTextInput = Animated.createAnimatedComponent(TextInput);
The animated TextInput:
<AnimatedTextInput
style={[styles.textInput, animatedTranslateStyle]}
onChangeText={text => onChangeText(text)}
value={value}
placeholder="Search for an item"
enablesReturnKeyAutomatically
clearButtonMode={'always'}
returnKeyType="search"
selectionColor="red"
/>
I used the animation on the react-native expo project.
I was going to rotate and change the opacity to my component(View) whenever the props are changed.
But I could not reproduce this animation.
Even if I remove the rotate animation, It doesn't work for the opacity animation.
This is my error screen.
And this is my some code.
...
let rotateValue = new Animated.Value(0);
let fadeValue = new Animated.Value(1);
const animationStart=()=>{
return Animated.parallel([
Animated.timing(rotateValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true
}),
Animated.timing(fadeValue, {
toValue: 0,
duration: 1000,
useNativeDriver: true
})
]).start();
};
React.useEffect(()=> {
animationStart();
}, [spinInfoData]);
.....
<Animated.View style={{
transform: [
{
rotateY: rotateValue.interpolate({
inputRange: [0, 1],
outputRange: [6, 0]
})
}
],
opacity: fadeValue,
display: "flex",
justifyContent: "center",
height: hp(spinSize),
flexDirection: "row",
marginTop: hp(spinSize / -6)
}}>
.......
You can fix the bug about the red screen like this.
transform: [
{
rotateY: rotateValue.interpolate({
inputRange: [0, 1],
outputRange: ['180deg', '0deg']
})
}
],
And please change your code for the reset the animation when props is changed like this.
const rotateValue = new useRef(new Animated.Value(0)).current;
const saveRotateValue = rotateValue.interpolate({
inputRange: [0, 1],
outputRange: ['180deg', '0deg']
});
....
// change the props
React.useEffect(()=> {
fadeValue.setValue(1); // reset the fade animation
rotateValue.setValue(0); // reset the rotate animation
Animated.parallel([
Animated.timing(rotateValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true
}),
Animated.timing(fadeValue, {
toValue: 0,
duration: 1000,
useNativeDriver: true
})
]).start();
}, [spinInfoData]);
.......
<Animated.View style={{
transform: [
{
rotateY: saveRotateValue
}
],
opacity: saveOpacity,
......