react-native-reanimated
react-native-reanimated copied to clipboard
Custom keyframe animations for web
Summary
This PR adds support for custom layout animations created via Keyframe
on web.
Known limitations
Currently originX
and originY
don't work because in CSS there's only transform-origin
property which needs both of those values at the same time (current approach doesn't make it easy to merge them).
Test plan
Tested on example app and the following code snippet:
Test code
import { StyleSheet, View, Text, Pressable } from 'react-native';
import React, { useState } from 'react';
import Animated, { Easing, Keyframe } from 'react-native-reanimated';
const entering = new Keyframe({
0: {
transform: [
{ translateX: -500 },
{ translateY: -300 },
{ scale: 1.25 },
{ skewY: '25deg' },
],
opacity: 0.3,
easing: Easing.cubic,
},
70: {
transform: [{ translateX: 250 }, { translateY: 100 }, { scale: 1.25 }],
opacity: 0.7,
},
});
const exiting = new Keyframe({
0: {
easing: Easing.exp,
},
100: {
transform: [
{ translateX: 700 },
{ translateY: 250 },
{ scale: 0.3 },
{ rotate: '225deg' },
],
opacity: 0,
},
});
export default function EmptyExample() {
const [show, setShow] = useState(true);
return (
<View style={styles.container}>
{show && (
<Animated.View
entering={entering.duration(1000)}
exiting={exiting}
style={styles.box}
/>
)}
<Pressable onPress={() => setShow((prev) => !prev)} style={styles.button}>
<Text style={{ color: 'white' }}> Click me! </Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
box: {
width: 250,
height: 250,
backgroundColor: '#782aeb',
},
button: {
width: 100,
height: 50,
backgroundColor: '#57b495',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-around',
borderRadius: 15,
position: 'absolute',
top: 10,
left: 10,
},
});