-
Notifications
You must be signed in to change notification settings - Fork 66
Open
Description
Description
I'm just trying to get a POC working, and using your base example I'm unable to have any change in my runtime without crashing. And when it doesn't crash, it doesn't apply the wanted changes anyway, and stops the animation.
Provide a Repro
import Rive, { RiveRef } from 'rive-react-native';
import { StyleSheet, Text, View, Pressable } from 'react-native';
import React, { useState, useRef } from 'react';
export default function RiveDemo() {
const [artboardName, setArtboardName] = useState('Avatar 2');
const [isPlaying, setIsPlaying] = useState(false);
const [isHappyState, setIsHappyState] = useState(false);
const [isSadState, setIsSadState] = useState(false);
const riveRef = useRef<RiveRef>(null);
// riveRef.current?.getBooleanState('isSad').then(console.log);
// riveRef.current?.getBooleanState('nope').then(console.log);
const toggleArtboard = () => {
setArtboardName(prev => (prev === 'Avatar 1' ? 'Avatar 2' : 'Avatar 1'));
// Reset might be needed depending on desired behavior when artboard changes
riveRef.current?.reset();
setIsPlaying(false); // Stop playback when artboard changes
// Reset mood states when artboard changes
setIsHappyState(false);
setIsSadState(false);
riveRef.current?.setInputState('avatar', 'isHappy', false);
riveRef.current?.setInputState('avatar', 'isSad', false);
};
const togglePlayPause = () => {
if (isPlaying) {
riveRef.current?.pause();
} else {
// Play the state machine defined in the Rive component
riveRef.current?.play(undefined, undefined, undefined, true);
}
setIsPlaying(!isPlaying);
};
const toggleHappy = () => {
const newState = !isHappyState;
riveRef.current?.setInputState('avatar', 'isHappy', newState);
setIsHappyState(newState);
// Optionally ensure moods are mutually exclusive
if (newState && isSadState) {
riveRef.current?.setInputState('avatar', 'isSad', false);
setIsSadState(false);
}
};
const toggleSad = () => {
const newState = !isSadState;
riveRef.current?.setInputState('avatar', 'isSad', newState);
setIsSadState(newState);
// Optionally ensure moods are mutually exclusive
if (newState && isHappyState) {
riveRef.current?.setInputState('avatar', 'isHappy', false);
setIsHappyState(false);
}
};
return (
<View style={styles.container}>
<Rive
ref={riveRef}
url="https://public.rive.app/community/runtime-files/2195-4346-avatar-pack-use-case.riv"
artboardName={artboardName} // Use state for artboardName
stateMachineName="avatar"
style={{ width: 300 }}
onStateChanged={(stateMachineName, stateName) => {
console.log('stateMachineName', stateMachineName);
console.log('stateName', stateName);
}}
animationName='happy'
onRiveEventReceived={(event) => {
console.log('event', event);
}}
children={<Text>Hello</Text>}
key={`${artboardName}-${isHappyState}-${isSadState}`}
/>
<View style={styles.controlsContainer}>
<Pressable onPress={toggleArtboard} style={styles.button}>
<Text style={styles.buttonText}>Artboard: {artboardName}</Text>
</Pressable>
<Pressable onPress={togglePlayPause} style={styles.button}>
<Text style={styles.buttonText}>{isPlaying ? 'Pause' : 'Play'}</Text>
</Pressable>
<Pressable onPress={toggleHappy} style={styles.button}>
<Text style={styles.buttonText}>Toggle Happy ({isHappyState ? 'On' : 'Off'})</Text>
</Pressable>
<Pressable onPress={toggleSad} style={styles.button}>
<Text style={styles.buttonText}>Toggle Sad ({isSadState ? 'On' : 'Off'})</Text>
</Pressable>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1, // Use flex: 1 instead of height: '100%'
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center', // Center content vertically
},
controlsContainer: {
marginTop: 20,
alignItems: 'center',
},
button: {
backgroundColor: '#007AFF',
paddingVertical: 10,
paddingHorizontal: 20,
borderRadius: 5,
marginBottom: 10,
},
buttonText: {
color: 'white',
fontSize: 16,
},
});
Source .riv/.rev file
Yours: https://public.rive.app/community/runtime-files/2195-4346-avatar-pack-use-case.riv
Expected behavior
Well, for the triggers to work :)
Device & Versions (please complete the following information)
- Device: Android emulator and Pixel 8a
- OS: Android 35
- NPM Version: 10.9.2
Additional context
This is just a POC, I wanted to start like that and then at some point swap parts on the chosen avatar from a list of parts displayed below. The POC is crashing, but should you find a solution, I guess replacing the body parts would be done through setInputState, like setInputState('avatar', 'mouth', '10')?
Metadata
Metadata
Assignees
Labels
No labels