1import { Image, ImageSource, ImageTransition } from 'expo-image'; 2import { useCallback, useState } from 'react'; 3import { StyleSheet, View } from 'react-native'; 4 5import Button from '../../components/Button'; 6import { FunctionParameter, useArguments } from '../../components/FunctionDemo'; 7import Configurator from '../../components/FunctionDemo/Configurator'; 8import { Colors } from '../../constants'; 9 10const generateSeed = () => 1 + Math.round(Math.random() * 10); 11 12const parameters: FunctionParameter[] = [ 13 { 14 name: 'Duration', 15 type: 'enum', 16 values: [ 17 { name: '0', value: 0 }, 18 { name: '300', value: 300 }, 19 { name: '2000', value: 2000 }, 20 ], 21 }, 22 { 23 name: 'Effect', 24 type: 'enum', 25 platforms: ['ios', 'web'], 26 values: [ 27 { name: 'cross-dissolve (default)', value: 'cross-dissolve' }, 28 { name: 'flip-from-left', value: 'flip-from-left' }, 29 { name: 'flip-from-right', value: 'flip-from-right' }, 30 { name: 'flip-from-top', value: 'flip-from-top' }, 31 { name: 'flip-from-bottom', value: 'flip-from-bottom' }, 32 { name: 'curl-up', value: 'curl-up' }, 33 { name: 'curl-down', value: 'curl-down' }, 34 { name: 'none', value: null }, 35 ], 36 }, 37 { 38 name: 'Timing', 39 type: 'enum', 40 platforms: ['ios', 'web'], 41 values: [ 42 { name: 'ease-in-out (default)', value: 'ease-in-out' }, 43 { name: 'ease-in', value: 'ease-in' }, 44 { name: 'ease-out', value: 'ease-out' }, 45 { name: 'linear', value: 'linear' }, 46 ], 47 }, 48 { 49 name: 'Use only fadeDuration', 50 type: 'boolean', 51 initial: false, 52 }, 53]; 54 55export default function ImageTransitionsScreen() { 56 const [source, setSource] = useState<ImageSource | null>({ uri: getRandomImageUri() }); 57 const [args, updateArgument] = useArguments(parameters); 58 const [duration, effect, timing, onlyFadeDuration] = args as [ 59 ImageTransition['duration'], 60 ImageTransition['effect'], 61 ImageTransition['timing'], 62 boolean, 63 ]; 64 65 const changeImage = useCallback(() => { 66 setSource({ uri: getRandomImageUri() }); 67 }, [source]); 68 69 const transition = onlyFadeDuration ? null : { duration, effect, timing }; 70 71 return ( 72 <View style={styles.container}> 73 <Image 74 style={styles.image} 75 source={source ?? []} 76 transition={transition} 77 fadeDuration={duration} 78 cachePolicy="none" 79 /> 80 81 <View style={styles.configurator}> 82 <Button style={styles.actionButton} title="Change image" onPress={changeImage} /> 83 84 <Configurator parameters={parameters} onChange={updateArgument} value={args} /> 85 </View> 86 </View> 87 ); 88} 89 90function getRandomImageUri(): string { 91 return `https://picsum.photos/seed/${generateSeed()}/3000/2000`; 92} 93 94const styles = StyleSheet.create({ 95 container: { 96 flex: 1, 97 padding: 20, 98 }, 99 image: { 100 height: 200, 101 borderWidth: 1, 102 borderColor: Colors.border, 103 }, 104 configurator: { 105 alignItems: 'flex-start', 106 padding: 10, 107 }, 108 actionButton: { 109 marginVertical: 15, 110 }, 111}); 112