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