React Native Animations simply not running - react-native

My issue with React Native seems to be project wide. Anything using the Animated API simply does not run. I am running React Native 0.49.2,
Nothing seems to be working, I have tried out several peoples code, with nothing ever happening. The issue to me seems to be whenever I call "Animated.Timing().start();" it never actually starts. Heres some short example code:
class Splash extends React.Component {
constructor(props){
super(props);
this.state = {
ShowSetup: true,
fadeAnim: new Animated.Value(0), // Initial value for opacity: 0
};
}
componentDidMount(){
this.Animator()
}
Animator(){
console.log("ANIMATOR RUNNING!")
Animated.timing( // Animate over time
this.state.fadeAnim, // The animated value to drive
{
toValue: 1, // Animate to opacity: 1 (opaque)
duration: 10000, // Make it take a while
}
).start(); // Starts the animation
}
render() {
let { fadeAnim } = this.state;
return (
<View style={{flex: 1, backgroundColor: 'blue'}}>
<Animated.View // Special animatable View
style={{
opacity: fadeAnim, // Bind opacity to animated value
}}
>
<Text>Fade In</Text>
</Animated.View>
</View>
);
}
}
No matter how long you wait, the value will not show up. Has become a big head scratcher for me as I am not sure what else to do

try this:
<View style={{flex: 1, backgroundColor: 'blue'}}>
<Animated.View // Special animatable View
style={{
opacity: this.state.fadeAnim, // Bind opacity to animated value
}}
>
<Text>Fade In</Text>
</Animated.View>
</View>
I think the fadeAnim variable you declare at the top of your render isn't being reassigned
-- EDIT --
Here is some animation code I've used, the render is implemented the same way you have it.
constructor() {
super();
this.state = {
topBoxOpacity: new Animated.Value(0),
leftBoxOpacity: new Animated.Value(0),
mainImageOpacity: new Animated.Value(0),
}
}
componentDidMount() {
const timing = Animated.timing;
Animated.parallel([
timing(this.state.leftBoxOpacity, {
toValue: 1,
duration: 700,
delay: 700,
}),
timing(this.state.topBoxOpacity, {
toValue: 1,
duration: 700,
delay: 1400,
}),
timing(this.state.mainImageOpacity, {
toValue: 1,
duration: 700,
delay: 2100,
}),
]).start();
}

Related

Restart React Native Animation When Component's Props Change

I have a React Native component rendering a notification text. I want the text to fade in and fade out after a small delay. When a new notification text is set, I want to restart the same animation.
I have the following code:
export default function Notification({ notification }) {
if (!notification) {
return null;
}
const [fadeAnimation] = useState(new Animated.Value(0));
useEffect(() => {
Animated.sequence([
Animated.timing(fadeAnimation, {
toValue: 1,
duration: 500,
useNativeDriver: true,
}),
Animated.delay(3000),
Animated.timing(fadeAnimation, {
toValue: 0,
duration: 500,
useNativeDriver: true,
})]).start()
}, []);
return (
<Animated.View style={{ opacity: fadeAnimation, }}>
<View style={styles.notificaton}>
<Text style={styles.text}>{notification}</Text>
</View>
</Animated.View >
)
}
I read that I should be able to reset the animation with setValue(0) again, however I do not know where and when to call it.
work for me
import React, { Component } from 'react';
import { Animated, View } from 'react-native';
class Testing extends Component {
constructor(props) {
super(props);
this.animatedValue = new Animated.Value(0);
}
componentDidUpdate(prevProps) {
if (prevProps.myProp !== this.props.myProp) {
this.startAnimation();
}
}
startAnimation() {
this.animatedValue.setValue(0);
Animated.timing(this.animatedValue, {
toValue: 1,
duration: 1000,
useNativeDriver: true,
}).start();
}
render() {
const { myProp } = this.props;
const opacity = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, 1],
});
return (
<View>
<Animated.Text style={{ opacity }}>
My prop val : {myProp}
</Animated.Text>
</View>
);
}
}
export default Testing;

Smooth rotation of React Native SVG Component [duplicate]

Rotation is a style transform and in RN, you can rotate things like this
render() {
return (
<View style={{transform:[{rotate: '10 deg'}]}}>
<Image source={require('./logo.png')} />
</View>
);
}
However, to animate things in RN, you have to use numbers, not strings. Can you still animate transforms in RN or do I have to come up with some kind of sprite sheet and change the Image src at some fps?
You can actually animate strings using the interpolate method. interpolate takes a range of values, typically 0 to 1 works well for most things, and interpolates them into a range of values (these could be strings, numbers, even functions that return a value).
What you would do is take an existing Animated value and pass it through the interpolate function like this:
spinValue = new Animated.Value(0);
// First set up animation
Animated.timing(
this.spinValue,
{
toValue: 1,
duration: 3000,
easing: Easing.linear, // Easing is an additional import from react-native
useNativeDriver: true // To make use of native driver for performance
}
).start()
// Next, interpolate beginning and end values (in this case 0 and 1)
const spin = this.spinValue.interpolate({
inputRange: [0, 1],
outputRange: ['0deg', '360deg']
})
Then use it in your component like this:
<Animated.Image
style={{transform: [{rotate: spin}] }}
source={{uri: 'somesource.png'}} />
In case if you want to do the rotation in loop, then add the Animated.timing in the Animated.loop
Animated.loop(
Animated.timing(
this.spinValue,
{
toValue: 1,
duration: 3000,
easing: Easing.linear,
useNativeDriver: true
}
)
).start();
Don't forget to add property useNativeDriver to ensure that you get the best performance out of this animation:
// First set up animation
Animated.timing(
this.state.spinValue,
{
toValue: 1,
duration: 3000,
easing: Easing.linear,
useNativeDriver: true
}
).start();
A note for the newbies like me:
For animating something else you need to wrap it in <Animated.SOMETHING> for this to work. Or else the compiler will panic on that transform property:
import {Animated} from 'react-native';
...
//animation code above
...
<Animated.View style={{transform: [{rotate: spinValue}] }} >
<YourComponent />
</Animated.View>
BUT for an image (Animated.Image), the example above is 100% goodness and correct.
Since most of the answers are functions & hooks based, herewith a complete example of class based Animation of Image.
import React from 'react';
import {
SafeAreaView,
View,
Animated,
Easing,
TouchableHighlight,
Text,
} from 'react-native';
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
rotateValueHolder: new Animated.Value(0)
};
}
componentDidMount = () => {
this.startImageRotateFunction();
}
startImageRotateFunction = () => {
Animated.loop(Animated.timing(this.state.rotateValueHolder, {
toValue: 1,
duration: 3000,
easing: Easing.linear,
useNativeDriver: false,
})).start();
};
render(){
return(
<SafeAreaView>
<View>
<Animated.Image
style={{
width: 200,
height: 200,
alignSelf:"center",
transform:
[
{
rotate: this.state.rotateValueHolder.interpolate(
{
inputRange: [0, 1],
outputRange: ['0deg', '360deg'],
}
)
}
],
}}
source={{uri:'https://raw.githubusercontent.com/AboutReact/sampleresource/master/old_logo.png',}}
/>
<TouchableHighlight
onPress={() => this.startImageRotateFunction()}>
<Text style={{textAlign:"center"}}>
CLICK HERE
</Text>
</TouchableHighlight>
</View>
</SafeAreaView>
);
}
}
Just gonna drop the solution I solved by stitching together parts from the answers here.
import { Feather } from '#expo/vector-icons'
import * as React from 'react'
import { TextStyle, Animated, Easing } from 'react-native'
import { Colors, FontSize } from '~/constants/Theme'
export const LoadingSpinner = React.memo(
({ color = Colors['sand'], size = FontSize['md'] - 1, fadeInDelay = 1000, ...props }: Props) => {
const fadeInValue = new Animated.Value(0)
const spinValue = new Animated.Value(0)
Animated.sequence([
Animated.delay(fadeInDelay),
Animated.timing(fadeInValue, {
toValue: 1,
duration: 1500,
easing: Easing.linear,
useNativeDriver: true,
}),
]).start()
Animated.loop(
Animated.timing(spinValue, {
toValue: 360,
duration: 300000,
easing: Easing.linear,
useNativeDriver: true,
})
).start()
return (
<Animated.View
style={{
opacity: fadeInValue,
transform: [{ rotate: spinValue }],
}}
>
<Feather
name="loader"
size={size}
style={{
color,
alignSelf: 'center',
}}
{...props.featherProps}
/>
</Animated.View>
)
}
)
type Props = {
color?: TextStyle['color']
size?: number
featherProps?: Partial<Omit<React.ComponentProps<typeof Feather>, 'style'>>
fadeInDelay?: number
}
Hope it helps 👍

Simple animation in react-native: moving an image from left to right

Can anyone share a code example for a react-native animation that moves an image from left to right, then move back to the starting point and repeat the motion?
Update:
The answer below helped a lot, but it didn't work. I used it to create the following animation that moves an image from left to right (I am using RN 0.62.2).
import React from 'react'
import { StyleSheet, View, Animated, Easing } from 'react-native';
const test = require('../images/test.png');
export class Splash extends React.Component {
constructor(props) {
super(props);
this.state = { xValue: new Animated.Value(-100) }
}
moveLR = () => {
Animated.timing(
this.state.xValue,
{
toValue: 100,
duration: 1000, // the duration of the animation
easing: Easing.linear, // the style of animation
useNativeDriver: true
}
).start();
}
moveRL = () => {
Animated.timing(
this.state.xValue,
{
toValue: -100,
duration: 3000, // the duration of the animation
easing: Easing.linear, // the style of animation
useNativeDriver: true
}
).start();
}
componentDidMount = () => {
this.moveLR();
}
render = () => {
return (
<View style={styles.mainContainer}>
<Animated.Image
style={{ width: 170, height: 146 }}
source={test}
style={{ width: 170, height: 146,
transform: [{ translateX: this.state.xValue }] }}>
</Animated.Image>
</View>
)
}
}
const styles = StyleSheet.create({
mainContainer: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
animationView: {
backgroundColor: 'red',
width: 100,
height: 100
}
})
Update by Yossi:
The code below didn't work for me in RN 0.62.2. I am accepting the answer, but I modified it and the code that is working is included now in the question.
Original answer:
Before getting started, I need to introduce you to the two types of values ​​for Animated animations:
Animated.Value () where we define a value, useful when we want to move an element on a single axis (X or Y), change the size of an element, etc. This is what we will use here, in this chapter, and this is what is used the most.
Animated.ValueXY () where we define a vector, useful for moving an element on two axes.
With these values, we can define several types of Animated animations. We will discover them one by one, testing them each time. in this example, I will only talk about Animated.timing ()
Here you can see an example of code which is gonna moove a red box from left to right and stop when the user decides, you can try it and tell if it worked for you :
// Test.js
import React from 'react'
import { StyleSheet, View, Animated, TouchableOpacity, Text, Easing } from 'react-native'
class Test extends React.Component {
constructor(props) {
super(props);
this.state = {
leftPosition : new Animated.Value (0)
}
this.mooveLR = this.mooveLR.bind(this);
this.mooveRL = this.mooveRL.bind(this);
this.stopAnimation = this.stopAnimation.bind(this);
}
stopAnimation () {
this.setState({
leftPosition : this.state.leftPosition // this forces the left position to remain the same considering the `componentDidMount` method already happened
})
}
mooveLR (){
Animated.timing(
this.state.leftPosition,
{
toValue: 100,
duration: 3000, // the duration of the animation
easing: Easing.linear, // the style of animation
}
).start() // starts this annimation once this method is called
}
mooveRL (){
Animated.timing(
this.state.leftPosition,
{
toValue: 0,
duration: 3000, // the duration of the animation
easing: Easing.linear, // the style of animation
}
).start() // starts this annimation once this method is called
}
componentDidMount(){
this.state.leftPosition === 0 ? this.mooveLR () : this.mooveRL () // repeats always when the red box return to its initial position : leftPosition === 0
}
render() {
return (
<View style={styles.main_container}>
<Animated.View style={[styles.animation_view, {left : this.state.leftPosition}]}>
</Animated.View>
<TouchableOpacity onPress = { () => this.stopAnimation ()}>
<Text>Stop animation</Text>
</TouchableOpacity>
</View>
)
}
}
const styles = StyleSheet.create({
main_container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center'
},
animation_view: {
backgroundColor: 'red',
width: 100,
height: 100
}
})
export default Test;
Hope it's gonna help
Regards
I have resolved this issue by doing:
import {
Easing
} from 'react-native';
Since I prefer using react hooks, I converted the solution Provided by #pacy.eth, and here it is for anyone who prefers to use react hooks.
import { View, Text, Animated, Easing } from 'react-native';
import React, { useEffect, useState } from 'react';
const Animate= ({ children, left, leftP, duration }) => {
const [leftPosition, setLeftPosition] = useState(new Animated.Value (leftP));
useEffect(() => {
left ? mooveLR() : mooveRL();
}, []);
const mooveLR = () => {
Animated.timing(leftPosition, {
toValue: 100,
duration, // the duration of the animation
easing: Easing.linear, // the style of animation
}).start(); // starts this annimation once this method is called
};
const mooveRL = () => {
Animated.timing(leftPosition, {
toValue: 0,
duration, // the duration of the animation
easing: Easing.linear, // the style of animation
}).start(); // starts this annimation once this method is called
};
return (
<Animated.View style={[{ left: leftPosition }]}>{children}</Animated.View>
);
};
export default Animate;
And with a little modifications, I made it reusable in severals ways:
one of my favorite ways, is by wrapping the component that I want to animate and I pass the the direction "left: true or false" I set the "leftP" which is the leftPosition (in my case I am hiding the view and with a click of a button I slide it in with the Animate component created) and the "duration" of the animation.
for ex:
<Animate left={false} duration={1000} leftP={-Dimensions.get('window').width}>
...
</Animate>

How to have a heart beat animation with React native?

I'm learning React native and I would like to have heart beat animation
I did that but it's not the good result, I would like to have heart beat.
If someone can help me it's would be very nice thanks a lot
import React, { PureComponent } from "react";
import { Animated, StyleSheet, Text, View } from "react-native";
export class Loading extends PureComponent {
constructor(props: any) {
super(props);
this.state = {
opacity: new Animated.Value(0),
};
}
public componentDidMount() {
Animated.timing(
this.state.opacity,
{
toValue: 100,
duration: 5000,
},
).start();
}
public render() {
return (
<View>
<View>
<Animated.View
style={[styles.animation, {
opacity: this.state.opacity,
transform: [
{
scale: this.state.opacity.interpolate({
inputRange: [0.5, 1],
outputRange: [1, 0.95],
}),
}]},
]}
/>
</View>
</View>
);
}
}
const styles = StyleSheet.create({
animation: {
backgroundColor: "red,
width: 100,
height: 100,
borderRadius: 50,
},
});
A bit late but here is my own heartbeat animation made with React Native's Animated module:
export const HeartbeatAnimation = (
value: Animated.Value,
minValue: number,
maxValue: number
) =>
Animated.loop(
Animated.sequence([
Animated.timing(value, {
toValue: maxValue,
duration: 100
}),
Animated.timing(value, {
toValue: minValue,
duration: 100
}),
Animated.timing(value, {
toValue: maxValue,
duration: 100
}),
Animated.timing(value, {
toValue: minValue,
duration: 2000
})
])
);
Try playing with the minValue and maxValue to get your favorite animation !
As you say you are new to react native, I would like to suggest you use a react-native-animatable library which is very helpful with some built-in animation and custom animation.
Here is a link of GitHub https://github.com/oblador/react-native-animatable for your solution which I mentioned below.
In this page, you can find different methods for how to use animatable library for animation in react-native.
Now as per your question here is a solution
you have to install react-native-animatable by
$ npm install react-native-animatable --save
Step 1:
import * as Animatable from 'react-native-animatable';
Step 2: Use this code
<Animatable.Text
animation="pulse"
easing="ease-out"
iterationCount="infinite"
style={{ textAlign: 'center' }}>
❤️
</Animatable.Text>
you can use Animated.loop like this
useEffect(() => {
// makes the sequence loop
Animated.loop(
// runs given animations in a sequence
Animated.sequence([
// increase size
Animated.timing(anim.current, {
toValue: 10,
duration: 2000,
}),
// decrease size
Animated.timing(anim.current, {
toValue: 1,
duration: 2000,
}),
])
).start();
}, []);
Check below the full code and Live preview in Snack.
import React, { useRef, useEffect } from 'react';
import { Text, View, StyleSheet, Animated } from 'react-native';
import { Ionicons } from '#expo/vector-icons';
export default function App() {
const anim = useRef(new Animated.Value(1));
useEffect(() => {
// makes the sequence loop
Animated.loop(
// runs given animations in a sequence
Animated.sequence([
// increase size
Animated.timing(anim.current, {
toValue: 10,
duration: 2000,
}),
// decrease size
Animated.timing(anim.current, {
toValue: 1,
duration: 2000,
}),
])
).start();
}, []);
return (
<View style={styles.container}>
<Animated.View style={{ transform: [{ scale: anim.current }] }}>
<Ionicons name="md-heart" size={32} color="red" />
</Animated.View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'rgb(254, 254, 254)',
padding: 8,
},
});
You can give React Native Lottie a go for a more flexible and appealing animation.
To get started, install it via:
Step 1: > npm i --save lottie-react-native#2.5.11
Step 2: > react-native link lottie-react-native
Step 3 : Go to Lottie Files, which is a collection of awesome animations done by the community. Search and choose a heartanimation that suits you and download the .jsonfile associated with it. Then proceed to render it as shown below:
import LottieView from 'lottie-react-native';
render() {
return (
<LottieView
ref={animation => {
this.animation = animation;
}}
source={require('../path/to/animation.json')}
/>
);
}
PS: I think This heart beat animation can fit your need. You can edit it's color and speed and then proceed to download it and use it in your app.
Use react-native-animatable:
<Animatable.Text
animation="pulse"
easing="ease-out"
iterationCount="infinite"
style={{ ... }}>❤️</Animatable.Text>
or...
<Animatable.View
animation="pulse"
easing="ease-out"
iterationCount="infinite"
style={{ ... }}>{children}</Animatable.View>
You can achieve that with react-native-animatable by creating your custom pulse animation:
const pulse = {
0: {
scale: 1,
},
0.5: {
scale: 1.5
},
1: {
scale: 1
}
}
Then, in your Animatable.View
<Animatable.View
animation={pulse}
easing="ease-out"
iterationCount="infinite"
>
<Text>PULSE ME</Text>
</Animatable.View>

react native animated repeat infinity

I have the following animation.
componentWillMount(){
this.animatedValue = new Animated.Value(300);
}
componentDidMount(){
Animated.timing( this.animatedValue , {
toValue: -100,
duration: 3000,
} ).start();
}
render() {
const animatedStyle = { marginLeft: this.animatedValue, marginRight: - this.animatedValue };
return (
<View style={{flexDirection: 'row', height: 100,}}>
<Animated.View style={[ animatedStyle,{backgroundColor: 'blue', width:100}]} />
</View>
);
}
I would like to repeat endless times. Anyone have any suggestions?
2019 solution:
Animated.loop(Animated.timing(this.animatedValue , {
toValue: -100,
duration: 3000,
})).start();
Pass a callback to Animated.start() that resets the Animated value and starts the animation again. For example:
componentDidMount(){
this.runAnimation();
}
runAnimation() {
this.animatedValue.setValue(300);
Animated.timing(this.animatedValue, {
toValue: -100,
duration: 3000,
}).start(() => this.runAnimation());
}
If you need to stop the animation at any point, take a look at this question/answer.