UNPKG

create-expo-cljs-app

Version:

Create a react native application with Expo and Shadow-CLJS!

459 lines (431 loc) 13.2 kB
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @format * @flow */ 'use strict'; const RNTesterButton = require('../../components/RNTesterButton'); const React = require('react'); const {Animated, Easing, StyleSheet, Text, View} = require('react-native'); const styles = StyleSheet.create({ content: { backgroundColor: 'deepskyblue', borderWidth: 1, borderColor: 'dodgerblue', padding: 20, margin: 20, borderRadius: 10, alignItems: 'center', }, rotatingImage: { width: 70, height: 70, }, }); exports.framework = 'React'; exports.title = 'Animated - Examples'; exports.category = 'UI'; exports.documentationURL = 'https://reactnative.dev/docs/animated'; exports.description = ('Animated provides a powerful ' + 'and easy-to-use API for building modern, ' + 'interactive user experiences.': string); exports.examples = [ { title: 'FadeInView', description: ('Uses a simple timing animation to ' + 'bring opacity from 0 to 1 when the component ' + 'mounts.': string), render: function(): React.Node { class FadeInView extends React.Component<$FlowFixMeProps, any> { constructor(props) { super(props); this.state = { fadeAnim: new Animated.Value(0), // opacity 0 }; } componentDidMount() { Animated.timing( // Uses easing functions this.state.fadeAnim, // The value to drive { // Target toValue: 1, // Configuration duration: 2000, useNativeDriver: false, }, ).start(); // Don't forget start! } render() { return ( <Animated.View // Special animatable View style={{ opacity: this.state.fadeAnim, // Binds }}> {this.props.children} </Animated.View> ); } } type Props = $ReadOnly<{||}>; type State = {|show: boolean|}; class FadeInExample extends React.Component<Props, State> { constructor(props: Props) { super(props); this.state = { show: true, }; } render() { return ( <View> <RNTesterButton onPress={() => { this.setState(state => ({show: !state.show})); }}> Press to {this.state.show ? 'Hide' : 'Show'} </RNTesterButton> {this.state.show && ( <FadeInView> <View style={styles.content}> <Text>FadeInView</Text> </View> </FadeInView> )} </View> ); } } return <FadeInExample />; }, }, { title: 'Transform Bounce', description: ('One `Animated.Value` is driven by a ' + 'spring with custom constants and mapped to an ' + 'ordered set of transforms. Each transform has ' + 'an interpolation to convert the value into the ' + 'right range and units.': string), render: function(): React.Node { this.anim = this.anim || new Animated.Value(0); return ( <View> <RNTesterButton onPress={() => { Animated.spring(this.anim, { // Returns to the start toValue: 0, // Velocity makes it move velocity: 3, // Slow tension: -10, // Oscillate a lot friction: 1, useNativeDriver: false, }).start(); }}> Press to Fling it! </RNTesterButton> <Animated.View style={[ styles.content, { transform: [ // Array order matters { scale: this.anim.interpolate({ inputRange: [0, 1], outputRange: [1, 4], }), }, { translateX: this.anim.interpolate({ inputRange: [0, 1], outputRange: [0, 500], }), }, { rotate: this.anim.interpolate({ inputRange: [0, 1], outputRange: [ '0deg', '360deg', // 'deg' or 'rad' ], }), }, ], }, ]}> <Text>Transforms!</Text> </Animated.View> </View> ); }, }, { title: 'Composite Animations with Easing', description: ('Sequence, parallel, delay, and ' + 'stagger with different easing functions.': string), render: function(): React.Node { this.anims = this.anims || [1, 2, 3].map(() => new Animated.Value(0)); return ( <View> <RNTesterButton onPress={() => { const timing = Animated.timing; Animated.sequence([ // One after the other timing(this.anims[0], { toValue: 200, easing: Easing.linear, useNativeDriver: false, }), Animated.delay(400), // Use with sequence timing(this.anims[0], { toValue: 0, // Springy easing: Easing.elastic(2), useNativeDriver: false, }), Animated.delay(400), Animated.stagger( 200, this.anims .map(anim => timing(anim, { toValue: 200, useNativeDriver: false, }), ) .concat( this.anims.map(anim => timing(anim, { toValue: 0, useNativeDriver: false, }), ), ), ), Animated.delay(400), Animated.parallel( [ Easing.inOut(Easing.quad), // Symmetric Easing.back(1.5), // Goes backwards first Easing.ease, // Default bezier ].map((easing, ii) => timing(this.anims[ii], { toValue: 320, easing, duration: 3000, useNativeDriver: false, }), ), ), Animated.delay(400), Animated.stagger( 200, this.anims.map(anim => timing(anim, { toValue: 0, // Like a ball easing: Easing.bounce, duration: 2000, useNativeDriver: false, }), ), ), ]).start(); }}> Press to Animate </RNTesterButton> {['Composite', 'Easing', 'Animations!'].map((text, ii) => ( <Animated.View key={text} style={[ styles.content, { left: this.anims[ii], }, ]}> <Text>{text}</Text> </Animated.View> ))} </View> ); }, }, { title: 'Rotating Images', description: 'Simple Animated.Image rotation.', render: function(): React.Node { this.anim = this.anim || new Animated.Value(0); return ( <View> <RNTesterButton onPress={() => { Animated.spring(this.anim, { // Returns to the start toValue: 0, // Velocity makes it move velocity: 3, // Slow tension: -10, // Oscillate a lot friction: 1, useNativeDriver: false, }).start(); }}> Press to Spin it! </RNTesterButton> <Animated.Image source={require('../../assets/bunny.png')} style={[ styles.rotatingImage, { transform: [ { scale: this.anim.interpolate({ inputRange: [0, 1], outputRange: [1, 10], }), }, { translateX: this.anim.interpolate({ inputRange: [0, 1], outputRange: [0, 100], }), }, { rotate: this.anim.interpolate({ inputRange: [0, 1], outputRange: [ '0deg', '360deg', // 'deg' or 'rad' ], }), }, ], }, ]} /> </View> ); }, }, { title: 'Moving box example', description: ('Click arrow buttons to move the box.' + 'Then hide the box and reveal it again.' + 'After that the box position will reset to initial position.': string), render: (): React.Node => { const containerWidth = 200; const boxSize = 50; const movingBoxStyles = StyleSheet.create({ container: { display: 'flex', alignItems: 'center', flexDirection: 'column', backgroundColor: '#fff', padding: 30, }, boxContainer: { backgroundColor: '#d3d3d3', height: boxSize, width: containerWidth, }, box: { width: boxSize, height: boxSize, margin: 0, }, buttonsContainer: { marginTop: 20, display: 'flex', flexDirection: 'row', justifyContent: 'space-between', width: containerWidth, }, }); type Props = $ReadOnly<{||}>; type State = {|boxVisible: boolean|}; class MovingBoxExample extends React.Component<Props, State> { x: Animated.Value; constructor(props) { super(props); this.x = new Animated.Value(0); this.state = { boxVisible: true, }; } render() { const {boxVisible} = this.state; const toggleText = boxVisible ? 'Hide' : 'Show'; return ( <View style={movingBoxStyles.container}> {this.renderBox()} <View style={movingBoxStyles.buttonsContainer}> <RNTesterButton onPress={() => this.moveTo(0)}> {'<-'} </RNTesterButton> <RNTesterButton onPress={this.toggleVisibility}> {toggleText} </RNTesterButton> <RNTesterButton onPress={() => this.moveTo(containerWidth - boxSize)}> {'->'} </RNTesterButton> </View> </View> ); } renderBox = () => { if (this.state.boxVisible) { const horizontalLocation = {transform: [{translateX: this.x}]}; return ( <View style={movingBoxStyles.boxContainer}> <Animated.View style={[ styles.content, movingBoxStyles.box, horizontalLocation, ]} /> </View> ); } else { return ( <View style={movingBoxStyles.boxContainer}> <Text>The box view is not being rendered</Text> </View> ); } }; moveTo = x => { Animated.timing(this.x, { toValue: x, duration: 1000, useNativeDriver: true, }).start(); }; toggleVisibility = () => { const {boxVisible} = this.state; this.setState({boxVisible: !boxVisible}); }; } return <MovingBoxExample />; }, }, { title: 'Continuous Interactions', description: ('Gesture events, chaining, 2D ' + 'values, interrupting and transitioning ' + 'animations, etc.': string), render: (): React.Node => ( <Text>Checkout the Gratuitous Animation App!</Text> ), }, ];