|
2 | 2 | Rive React Native Quick Start (Nitro) |
3 | 3 |
|
4 | 4 | Resources: |
5 | | -
|
6 | | - - Getting Started with Rive + React Native: https://rive.app/docs/runtimes/react-native/react-native |
| 5 | + - Getting Started: https://rive.app/docs/runtimes/react-native/react-native |
7 | 6 | - Data Binding: https://rive.app/docs/runtimes/data-binding |
8 | | - - Setting and reading view model properties: https://rive.app/docs/runtimes/data-binding#observability |
9 | 7 | */ |
10 | 8 |
|
11 | | -import { useEffect, useState } from 'react'; |
12 | | -import { |
13 | | - Button, |
14 | | - SafeAreaView, |
15 | | - ScrollView, |
16 | | - StyleSheet, |
17 | | - Text, |
18 | | -} from 'react-native'; |
| 9 | +import { useEffect } from 'react'; |
| 10 | +import { Button, SafeAreaView, ScrollView, StyleSheet } from 'react-native'; |
19 | 11 | import { |
20 | 12 | RiveView, |
| 13 | + useRive, |
21 | 14 | useRiveFile, |
22 | 15 | useRiveNumber, |
23 | 16 | useRiveTrigger, |
24 | 17 | Fit, |
25 | 18 | DataBindMode, |
26 | | - type ViewModelInstance, |
27 | | - type RiveViewRef, |
28 | 19 | } from '@rive-app/react-native'; |
29 | 20 | import type { Metadata } from '../helpers/metadata'; |
30 | 21 |
|
31 | 22 | export default function QuickStart() { |
32 | | - const { riveFile, error: fileError } = useRiveFile( |
| 23 | + const { riveFile } = useRiveFile( |
33 | 24 | require('../../assets/rive/quick_start.riv') |
34 | 25 | ); |
35 | | - const [riveViewRef, setRiveViewRef] = useState<RiveViewRef | null>(null); |
36 | | - const [viewModelInstance, setViewModelInstance] = |
37 | | - useState<ViewModelInstance | null>(null); |
38 | | - |
39 | | - // Get the ViewModelInstance once the RiveView is ready |
40 | | - useEffect(() => { |
41 | | - if (riveViewRef) { |
42 | | - const vmi = riveViewRef.getViewModelInstance(); |
43 | | - setViewModelInstance(vmi ?? null); |
44 | | - } |
45 | | - }, [riveViewRef]); |
| 26 | + const { riveViewRef, setHybridRef } = useRive(); |
| 27 | + const viewModelInstance = riveViewRef?.getViewModelInstance(); |
46 | 28 |
|
47 | | - // This is how you read and set properties from your Rive View Model |
48 | 29 | const { value: health, setValue: setHealth } = useRiveNumber( |
49 | 30 | 'health', |
50 | 31 | viewModelInstance |
51 | 32 | ); |
52 | 33 |
|
53 | | - // Reference a Trigger from your View Model |
54 | 34 | const { trigger: gameOverTrigger } = useRiveTrigger( |
55 | 35 | 'gameOver', |
56 | 36 | viewModelInstance, |
57 | | - { |
58 | | - onTrigger: () => { |
59 | | - // Listen for a Trigger event, whether it comes from the Rive app or from the code |
60 | | - console.log('Game Over Triggered'); |
61 | | - }, |
62 | | - } |
| 37 | + { onTrigger: () => console.log('Game Over Triggered') } |
63 | 38 | ); |
64 | 39 |
|
65 | 40 | useEffect(() => { |
66 | 41 | if (viewModelInstance && setHealth) { |
67 | | - // Set the initial health value |
68 | 42 | setHealth(9); |
69 | 43 | } |
70 | 44 | }, [viewModelInstance, setHealth]); |
71 | 45 |
|
72 | 46 | const handleTakeDamage = () => { |
73 | 47 | if (health !== undefined && setHealth) { |
74 | 48 | setHealth(health - 7); |
75 | | - // If all state machines have settled, you might need to wake the state machine back up. |
76 | | - // This can happen when all animations have finished playing. |
77 | 49 | riveViewRef?.play(); |
78 | 50 | } |
79 | 51 | }; |
80 | 52 |
|
81 | 53 | const handleMaxHealth = () => { |
82 | | - if (setHealth) { |
83 | | - setHealth(100); |
84 | | - riveViewRef?.play(); |
85 | | - } |
| 54 | + setHealth?.(100); |
| 55 | + riveViewRef?.play(); |
86 | 56 | }; |
87 | 57 |
|
88 | 58 | const handleGameOver = () => { |
89 | | - if (setHealth && gameOverTrigger) { |
90 | | - setHealth(0); |
91 | | - gameOverTrigger(); |
92 | | - riveViewRef?.play(); |
93 | | - } |
| 59 | + setHealth?.(0); |
| 60 | + gameOverTrigger?.(); |
| 61 | + riveViewRef?.play(); |
94 | 62 | }; |
95 | 63 |
|
96 | | - if (fileError) { |
97 | | - return ( |
98 | | - <SafeAreaView style={styles.safeAreaViewContainer}> |
99 | | - <Text style={styles.errorText}>{fileError}</Text> |
100 | | - </SafeAreaView> |
101 | | - ); |
102 | | - } |
103 | | - |
104 | 64 | return ( |
105 | 65 | <SafeAreaView style={styles.safeAreaViewContainer}> |
106 | 66 | <ScrollView contentContainerStyle={styles.container}> |
107 | 67 | {riveFile && ( |
108 | 68 | <RiveView |
109 | | - hybridRef={{ |
110 | | - f: (ref) => setRiveViewRef(ref), |
111 | | - }} |
| 69 | + hybridRef={setHybridRef} |
112 | 70 | file={riveFile} |
113 | 71 | fit={Fit.Layout} |
114 | 72 | style={styles.animation} |
115 | 73 | autoPlay={true} |
116 | | - // DataBindMode.Auto uses the view model instance from your Rive file |
117 | 74 | dataBind={DataBindMode.Auto} |
118 | | - // Alternative binding options: |
119 | | - // dataBind={{ byName: 'SomeName' }} |
120 | | - // dataBind={DataBindMode.None} |
121 | 75 | /> |
122 | 76 | )} |
123 | 77 | </ScrollView> |
@@ -146,9 +100,4 @@ const styles = StyleSheet.create({ |
146 | 100 | width: '100%', |
147 | 101 | height: 400, |
148 | 102 | }, |
149 | | - errorText: { |
150 | | - color: 'red', |
151 | | - textAlign: 'center', |
152 | | - padding: 20, |
153 | | - }, |
154 | 103 | }); |
0 commit comments