-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathuseStateMachineInputs.ts
More file actions
62 lines (52 loc) · 1.78 KB
/
Copy pathuseStateMachineInputs.ts
File metadata and controls
62 lines (52 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import { EventType, StateMachineInput, Rive } from '@rive-app/canvas';
import { useCallback, useEffect, useState } from 'react';
/**
* Custom hook for fetching multiple stateMachine inputs from a rive file.
* Particularly useful for fetching multiple inputs from a variable number of input names.
*
* @param rive - Rive instance
* @param stateMachineName - Name of the state machine
* @param inputNames - Name and initial value of the inputs
* @returns StateMachineInput[]
*/
export default function useStateMachineInputs(
rive: Rive | null,
stateMachineName?: string,
inputNames?: {
name: string;
initialValue?: number | boolean;
}[]
) {
const [inputs, setInputs] = useState<StateMachineInput[]>([]);
useEffect(() => {
const syncInputs = () => {
if (!rive || !stateMachineName || !inputNames) return;
const riveInputs = rive.stateMachineInputs(stateMachineName);
if (!riveInputs) return;
// To optimize lookup time from O(n) to O(1) in the following loop
const riveInputLookup = new Map<string, StateMachineInput>(
riveInputs.map(input => [input.name, input])
);
setInputs(() => {
// Iterate over inputNames instead of riveInputs to preserve array order
return inputNames
.filter(inputName => riveInputLookup.has(inputName.name))
.map(inputName => {
const riveInput = riveInputLookup.get(inputName.name)!;
if (inputName.initialValue !== undefined) {
riveInput.value = inputName.initialValue;
}
return riveInput;
});
});
};
syncInputs();
if (rive) {
rive.on(EventType.Load, syncInputs);
return () => {
rive.off(EventType.Load, syncInputs);
};
}
}, [rive]);
return inputs;
}