exodeui-react-native 1.0.6 → 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/ExodeUIView.tsx +15 -5
- package/src/engine.ts +54 -0
- package/src/useExodeUI.ts +11 -1
package/package.json
CHANGED
package/src/ExodeUIView.tsx
CHANGED
|
@@ -11,18 +11,20 @@ export interface ExodeUIViewProps {
|
|
|
11
11
|
autoPlay?: boolean;
|
|
12
12
|
fit?: Fit;
|
|
13
13
|
alignment?: Alignment;
|
|
14
|
-
onReady?: (engine: any) => void;
|
|
14
|
+
onReady?: (engine: any) => void;
|
|
15
15
|
onTrigger?: (triggerName: string, animationName: string) => void;
|
|
16
16
|
onInputUpdate?: (nameOrId: string, value: any) => void;
|
|
17
|
-
onComponentChange?: (event: ComponentEvent) => void;
|
|
18
|
-
onToggle?: (name: string, checked: boolean) => void;
|
|
19
|
-
onInputChange?: (name: string, text: string) => void;
|
|
17
|
+
onComponentChange?: (event: ComponentEvent) => void;
|
|
18
|
+
onToggle?: (name: string, checked: boolean) => void;
|
|
19
|
+
onInputChange?: (name: string, text: string) => void;
|
|
20
20
|
onInputFocus?: (name: string) => void;
|
|
21
21
|
onInputBlur?: (name: string) => void;
|
|
22
|
+
onButtonClick?: (name: string, objectId: string) => void;
|
|
23
|
+
onGraphPointClick?: (event: { objectId: string; componentName: string; datasetIndex: number; pointIndex: number; value: number; label: string }) => void;
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
export const ExodeUIView = forwardRef<any, ExodeUIViewProps>(
|
|
25
|
-
({ artboard, src, style, autoPlay = true, fit = 'Contain', alignment = 'Center', onReady, onTrigger, onInputUpdate, onInputFocus, onInputBlur, onToggle, onInputChange, onComponentChange }, ref) => {
|
|
27
|
+
({ artboard, src, style, autoPlay = true, fit = 'Contain', alignment = 'Center', onReady, onTrigger, onInputUpdate, onInputFocus, onInputBlur, onToggle, onInputChange, onComponentChange, onButtonClick, onGraphPointClick }, ref) => {
|
|
26
28
|
|
|
27
29
|
const engineRef = useRef<ExodeUIEngine>(new ExodeUIEngine());
|
|
28
30
|
const [picture, setPicture] = useState<SkPicture | null>(null);
|
|
@@ -72,6 +74,14 @@ export const ExodeUIView = forwardRef<any, ExodeUIViewProps>(
|
|
|
72
74
|
if (onComponentChange) engineRef.current.setComponentChangeCallback(onComponentChange);
|
|
73
75
|
}, [onComponentChange]);
|
|
74
76
|
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
if (onButtonClick) engineRef.current.setButtonClickCallback(onButtonClick);
|
|
79
|
+
}, [onButtonClick]);
|
|
80
|
+
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (onGraphPointClick) engineRef.current.setGraphPointClickCallback(onGraphPointClick);
|
|
83
|
+
}, [onGraphPointClick]);
|
|
84
|
+
|
|
75
85
|
// Load Artboard
|
|
76
86
|
useEffect(() => {
|
|
77
87
|
const loadArtboard = async () => {
|
package/src/engine.ts
CHANGED
|
@@ -35,6 +35,8 @@ export class ExodeUIEngine {
|
|
|
35
35
|
private onInputChange?: (name: string, text: string) => void;
|
|
36
36
|
private onInputFocus?: (name: string) => void;
|
|
37
37
|
private onInputBlur?: (name: string) => void;
|
|
38
|
+
private onButtonClick?: (name: string, objectId: string) => void;
|
|
39
|
+
private onGraphPointClick?: (event: { objectId: string; componentName: string; datasetIndex: number; pointIndex: number; value: number; label: string }) => void;
|
|
38
40
|
|
|
39
41
|
// Track triggers that were just fired in the current frame
|
|
40
42
|
private justFiredTriggers: Set<string> = new Set();
|
|
@@ -78,6 +80,12 @@ export class ExodeUIEngine {
|
|
|
78
80
|
setInputBlurCallback(cb: (name: string) => void) {
|
|
79
81
|
this.onInputBlur = cb;
|
|
80
82
|
}
|
|
83
|
+
setButtonClickCallback(cb: (name: string, objectId: string) => void) {
|
|
84
|
+
this.onButtonClick = cb;
|
|
85
|
+
}
|
|
86
|
+
setGraphPointClickCallback(cb: (event: { objectId: string; componentName: string; datasetIndex: number; pointIndex: number; value: number; label: string }) => void) {
|
|
87
|
+
this.onGraphPointClick = cb;
|
|
88
|
+
}
|
|
81
89
|
|
|
82
90
|
constructor() {}
|
|
83
91
|
|
|
@@ -964,6 +972,15 @@ export class ExodeUIEngine {
|
|
|
964
972
|
}
|
|
965
973
|
}
|
|
966
974
|
|
|
975
|
+
if (targetObj.type === 'Component' && (targetObj as any).variant === 'button') {
|
|
976
|
+
if (type === 'click' || type === 'PointerDown') {
|
|
977
|
+
if (this.onButtonClick) this.onButtonClick(targetObj.name, targetObj.id);
|
|
978
|
+
if (this.onComponentChange) {
|
|
979
|
+
this.onComponentChange({ objectId: targetObj.id, componentName: targetObj.name, variant: 'button', property: 'click', value: true });
|
|
980
|
+
}
|
|
981
|
+
}
|
|
982
|
+
}
|
|
983
|
+
|
|
967
984
|
if (targetObj.type === 'Component' && (targetObj as any).variant === 'slider') {
|
|
968
985
|
if (type === 'PointerDown') {
|
|
969
986
|
this.draggingSliderId = targetObj.id;
|
|
@@ -1021,6 +1038,43 @@ export class ExodeUIEngine {
|
|
|
1021
1038
|
}
|
|
1022
1039
|
}
|
|
1023
1040
|
}
|
|
1041
|
+
|
|
1042
|
+
if (targetObj.type === 'LineGraph') {
|
|
1043
|
+
if (type === 'click' || type === 'PointerDown') {
|
|
1044
|
+
const geom = targetObj.geometry as any;
|
|
1045
|
+
const datasets = geom?.datasets || [];
|
|
1046
|
+
const state = this.objectStates.get(targetObj.id);
|
|
1047
|
+
const objW = state?.width || geom?.width || 200;
|
|
1048
|
+
const objH = state?.height || geom?.height || 150;
|
|
1049
|
+
const world = this.getWorldTransform(targetObj.id);
|
|
1050
|
+
const axisMarginL = 30;
|
|
1051
|
+
const axisMarginB = 20;
|
|
1052
|
+
const plotW = objW - axisMarginL;
|
|
1053
|
+
const plotH = objH - axisMarginB;
|
|
1054
|
+
let globalMax = 1;
|
|
1055
|
+
datasets.forEach((ds: any) => { const m = Math.max(...(ds.data || [0])); if (m > globalMax) globalMax = m; });
|
|
1056
|
+
|
|
1057
|
+
let closestDist = Infinity;
|
|
1058
|
+
let closestResult: any = null;
|
|
1059
|
+
datasets.forEach((ds: any, dIdx: number) => {
|
|
1060
|
+
const data = ds.data || [];
|
|
1061
|
+
const stepX = plotW / Math.max(data.length - 1, 1);
|
|
1062
|
+
data.forEach((val: number, pIdx: number) => {
|
|
1063
|
+
const px = world.x - objW/2 + axisMarginL + pIdx * stepX;
|
|
1064
|
+
const py = world.y + objH/2 - axisMarginB - (val / globalMax) * plotH;
|
|
1065
|
+
const dist = Math.sqrt((x - px) ** 2 + (y - py) ** 2);
|
|
1066
|
+
if (dist < closestDist) { closestDist = dist; closestResult = { dIdx, pIdx, val, label: ds.label || `Dataset ${dIdx + 1}` }; }
|
|
1067
|
+
});
|
|
1068
|
+
});
|
|
1069
|
+
|
|
1070
|
+
if (closestResult && closestDist < 20 && this.onGraphPointClick) {
|
|
1071
|
+
this.onGraphPointClick({ objectId: targetObj.id, componentName: targetObj.name, datasetIndex: closestResult.dIdx, pointIndex: closestResult.pIdx, value: closestResult.val, label: closestResult.label });
|
|
1072
|
+
}
|
|
1073
|
+
if (this.onComponentChange) {
|
|
1074
|
+
this.onComponentChange({ objectId: targetObj.id, componentName: targetObj.name, variant: 'linegraph', property: 'click', value: closestResult?.val ?? null });
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1024
1078
|
}
|
|
1025
1079
|
}
|
|
1026
1080
|
|
package/src/useExodeUI.ts
CHANGED
|
@@ -40,6 +40,14 @@ export function useExodeUI() {
|
|
|
40
40
|
engine?.updateObjectOptions(id, newOptions);
|
|
41
41
|
}, [engine]);
|
|
42
42
|
|
|
43
|
+
const onButtonClick = useCallback((cb: (name: string, objectId: string) => void) => {
|
|
44
|
+
engine?.setButtonClickCallback(cb);
|
|
45
|
+
}, [engine]);
|
|
46
|
+
|
|
47
|
+
const onGraphPointClick = useCallback((cb: (event: { objectId: string; componentName: string; datasetIndex: number; pointIndex: number; value: number; label: string }) => void) => {
|
|
48
|
+
engine?.setGraphPointClickCallback(cb);
|
|
49
|
+
}, [engine]);
|
|
50
|
+
|
|
43
51
|
return {
|
|
44
52
|
setEngine,
|
|
45
53
|
engine,
|
|
@@ -51,6 +59,8 @@ export function useExodeUI() {
|
|
|
51
59
|
fireTrigger,
|
|
52
60
|
updateConstraint,
|
|
53
61
|
updateGraphData,
|
|
54
|
-
updateObjectOptions
|
|
62
|
+
updateObjectOptions,
|
|
63
|
+
onButtonClick,
|
|
64
|
+
onGraphPointClick,
|
|
55
65
|
};
|
|
56
66
|
}
|