@ntalmagor/3drize-viewer 0.1.14 → 0.1.16
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/dist/components/AnimatedObject.d.ts.map +1 -1
- package/dist/components/AnimatedObject.js +73 -72
- package/dist/components/CreatedObject.d.ts.map +1 -1
- package/dist/components/CreatedObject.js +0 -1
- package/dist/components/CustomPrimitive.d.ts +1 -3
- package/dist/components/CustomPrimitive.d.ts.map +1 -1
- package/dist/components/CustomPrimitive.js +1 -1
- package/dist/components/ObjectNode.d.ts.map +1 -1
- package/dist/components/ObjectNode.js +3 -3
- package/dist/components/ObjectNodeApi.d.ts +13 -0
- package/dist/components/ObjectNodeApi.d.ts.map +1 -0
- package/dist/components/ObjectNodeApi.js +18 -0
- package/dist/components/ObjectsRenderer.d.ts +2 -1
- package/dist/components/ObjectsRenderer.d.ts.map +1 -1
- package/dist/components/ObjectsRenderer.js +21 -2
- package/dist/components/ProjectLoader.d.ts.map +1 -1
- package/dist/components/ProjectLoader.js +26 -2
- package/dist/components/SceneBuilder.d.ts.map +1 -1
- package/dist/components/SceneBuilder.js +1 -20
- package/dist/constants.d.ts +1 -1
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +7 -1
- package/dist/hooks/useAnimationEvents.d.ts.map +1 -1
- package/dist/hooks/useAnimationEvents.js +22 -1
- package/dist/hooks/useObjectAnimation.d.ts.map +1 -1
- package/dist/hooks/useObjectAnimation.js +16 -0
- package/dist/hooks/useSequenceAnimation.d.ts +14 -0
- package/dist/hooks/useSequenceAnimation.d.ts.map +1 -0
- package/dist/hooks/useSequenceAnimation.js +258 -0
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimatedObject.d.ts","sourceRoot":"","sources":["../../src/components/AnimatedObject.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAQvG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,aAAa,EAAE,qBAAqB,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACjH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAE3B;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,
|
|
1
|
+
{"version":3,"file":"AnimatedObject.d.ts","sourceRoot":"","sources":["../../src/components/AnimatedObject.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+C,MAAM,OAAO,CAAC;AAEpE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACtC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAQvG,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,iBAAiB,CAAC;IACtC,aAAa,EAAE,qBAAqB,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACjH,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;IACvD,MAAM,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IAC/B,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,eAAe,CAAC,EAAE,OAAO,CAAC;CAE3B;AAED,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,mBAAmB,CA+JvD,CAAC;AAGH,eAAe,cAAc,CAAC"}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { useRef, useEffect, useCallback, memo } from 'react';
|
|
3
|
-
import { useFrame } from '@react-three/fiber';
|
|
4
|
-
import { useAnimationEvents } from '../hooks/useAnimationEvents.js';
|
|
5
3
|
import { usePathAnimation } from '../hooks/usePathAnimation.js';
|
|
6
|
-
import { AnimationsManager } from '@ntalmagor/3drize-core';
|
|
7
|
-
import { applyAnchorSettings } from '../utils/anchorUtils.js';
|
|
8
4
|
import EffectsGroup from './EffectsGroup.js';
|
|
9
5
|
import { useObjectAnimation } from '../hooks/useObjectAnimation.js';
|
|
10
6
|
export const AnimatedObject = memo(({ stateKey, transitionSettings, createdObject,
|
|
@@ -47,74 +43,79 @@ visible = true, children, parentRef, handleObjectClick, onPointerEnter, onPointe
|
|
|
47
43
|
animProgress.current = 0;
|
|
48
44
|
}, [position, scale, rotation, targetPosition, targetScale, targetRotation]);
|
|
49
45
|
useEffect(() => { syncTransform(); }, [position, scale, rotation, targetPosition, targetScale, targetRotation]);
|
|
50
|
-
useAnimationEvents({
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
})
|
|
46
|
+
// useAnimationEvents({
|
|
47
|
+
// onStepStart: (event) => {
|
|
48
|
+
// console.log('Received animation event:', event);
|
|
49
|
+
// if (!event.step?.transitions) return;
|
|
50
|
+
// const d = event.step.duration || 1;
|
|
51
|
+
// for (const { state, properties, pathId } of event.step.transitions) {
|
|
52
|
+
// console.log(`Animation event for state: ${state}, object stateKey: ${stateKey}`);
|
|
53
|
+
// if (state !== stateKey) continue;
|
|
54
|
+
// if (properties.to.visible === false) {
|
|
55
|
+
// if (groupRef.current) groupRef.current.visible = false;
|
|
56
|
+
// } else {
|
|
57
|
+
// if (groupRef.current) groupRef.current.visible = true;
|
|
58
|
+
// stepDuration.current = d;
|
|
59
|
+
// stepEase.current = event.step.ease || 'linear';
|
|
60
|
+
// animationStartTime.current = performance.now();
|
|
61
|
+
// animProgress.current = 0;
|
|
62
|
+
// if (pathId) {
|
|
63
|
+
// startPathAnimation(pathId, d, { ease: stepEase.current });
|
|
64
|
+
// } else {
|
|
65
|
+
// const cur = targetRef.current;
|
|
66
|
+
// baseRef.current = {
|
|
67
|
+
// position: (properties.from?.position ? [...properties.from.position] : cur.position) as [number, number, number],
|
|
68
|
+
// rotation: (properties.from?.rotation ? [...properties.from.rotation] : cur.rotation) as [number, number, number],
|
|
69
|
+
// scale: (properties.from?.scale ? [...properties.from.scale] : cur.scale) as [number, number, number],
|
|
70
|
+
// };
|
|
71
|
+
// targetRef.current = {
|
|
72
|
+
// position: (properties.to?.position ? [...properties.to.position] : cur.position) as [number, number, number],
|
|
73
|
+
// rotation: (properties.to?.rotation ? [...properties.to.rotation] : cur.rotation) as [number, number, number],
|
|
74
|
+
// scale: (properties.to?.scale ? [...properties.to.scale] : cur.scale) as [number, number, number],
|
|
75
|
+
// };
|
|
76
|
+
// }
|
|
77
|
+
// }
|
|
78
|
+
// }
|
|
79
|
+
// },
|
|
80
|
+
// });
|
|
81
|
+
// const applyTransformProgress = useCallback(() => {
|
|
82
|
+
// const obj = groupRef.current;
|
|
83
|
+
// if (!obj || animationStartTime.current === null) return;
|
|
84
|
+
// const p = AnimationsManager.getProgressFromTime(
|
|
85
|
+
// animationStartTime.current,
|
|
86
|
+
// stepDuration.current,
|
|
87
|
+
// stepEase.current,
|
|
88
|
+
// );
|
|
89
|
+
// animProgress.current = p;
|
|
90
|
+
// const b = baseRef.current, t = targetRef.current;
|
|
91
|
+
// obj.position.set(
|
|
92
|
+
// b.position[0] + (t.position[0] - b.position[0]) * p,
|
|
93
|
+
// b.position[1] + (t.position[1] - b.position[1]) * p,
|
|
94
|
+
// b.position[2] + (t.position[2] - b.position[2]) * p,
|
|
95
|
+
// );
|
|
96
|
+
// obj.scale.set(
|
|
97
|
+
// b.scale[0] + (t.scale[0] - b.scale[0]) * p,
|
|
98
|
+
// b.scale[1] + (t.scale[1] - b.scale[1]) * p,
|
|
99
|
+
// b.scale[2] + (t.scale[2] - b.scale[2]) * p,
|
|
100
|
+
// );
|
|
101
|
+
// obj.rotation.set(
|
|
102
|
+
// b.rotation[0] + (t.rotation[0] - b.rotation[0]) * p,
|
|
103
|
+
// b.rotation[1] + (t.rotation[1] - b.rotation[1]) * p,
|
|
104
|
+
// b.rotation[2] + (t.rotation[2] - b.rotation[2]) * p,
|
|
105
|
+
// );
|
|
106
|
+
// }, []);
|
|
107
|
+
// useFrame((_state, delta) => {
|
|
108
|
+
// if (!visible || !groupRef.current) return;
|
|
109
|
+
// if (animProgress.current < 1) {
|
|
110
|
+
// if (isPathAnimating()) {
|
|
111
|
+
// const still = updatePathAnimation(delta, groupRef.current);
|
|
112
|
+
// if (!still) { animProgress.current = 1; animationStartTime.current = null; }
|
|
113
|
+
// } else if (animationStartTime.current !== null) {
|
|
114
|
+
// applyTransformProgress();
|
|
115
|
+
// }
|
|
116
|
+
// }
|
|
117
|
+
// if (anchor) applyAnchorSettings(anchor, groupRef.current, rotation);
|
|
118
|
+
// });
|
|
118
119
|
const onClick = (e) => {
|
|
119
120
|
if (handleObjectClick && groupRef.current) {
|
|
120
121
|
handleObjectClick(createdObject, groupRef.current, e);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreatedObject.d.ts","sourceRoot":"","sources":["../../src/components/CreatedObject.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAEjE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"CreatedObject.d.ts","sourceRoot":"","sources":["../../src/components/CreatedObject.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAEjE,OAAO,KAAK,EAAG,qBAAqB,EAAkC,MAAM,wBAAwB,CAAC;AAOrG,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAMjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWrD,UAAU,kBAAkB;IAC1B,aAAa,EAAE,qBAAqB,CAAC;IACrC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAElH;AAED,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAiK9C,CAAC;AAIH,eAAe,aAAa,CAAC"}
|
|
@@ -7,7 +7,6 @@ import { RigidBody } from '@react-three/rapier';
|
|
|
7
7
|
import { cameraManager } from "../utils/CameraSingleton.js";
|
|
8
8
|
import AnimatedObject from "./AnimatedObject.js";
|
|
9
9
|
import { useFrameEffects } from "../hooks/useFrameEffects.js";
|
|
10
|
-
// import { useSceneClick } from "~/contextProviders/SceneClickContext";
|
|
11
10
|
import { useObjectEdges } from "../hooks/useObjectEdges.js";
|
|
12
11
|
const CreatedObject = memo(({ createdObject, children, shouldApply3driseMaterial = true, onObjectReady, handleObjectClick, }) => {
|
|
13
12
|
const isSelected = false;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { type
|
|
2
|
+
import { type CreatedObjectSettings } from "@ntalmagor/3drize-core";
|
|
3
3
|
import { Object3D } from "three";
|
|
4
4
|
import { type ThreeEvent } from '@react-three/fiber';
|
|
5
5
|
interface CustomPrimitiveProps {
|
|
6
6
|
createdObject: CreatedObjectSettings;
|
|
7
|
-
cameraSettings: CameraState;
|
|
8
|
-
updateObjectSettings?: (updatedSettings: CreatedObjectSettings) => void;
|
|
9
7
|
onObjectReady?: (object: CreatedObjectSettings, ref: Object3D) => void;
|
|
10
8
|
handleObjectClick?: (createdObject: CreatedObjectSettings, ref: Object3D, event: ThreeEvent<MouseEvent>) => void;
|
|
11
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CustomPrimitive.d.ts","sourceRoot":"","sources":["../../src/components/CustomPrimitive.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAEjE,OAAO,
|
|
1
|
+
{"version":3,"file":"CustomPrimitive.d.ts","sourceRoot":"","sources":["../../src/components/CustomPrimitive.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4C,MAAM,OAAO,CAAC;AAEjE,OAAO,EAAoB,KAAK,qBAAqB,EAI5B,MAAM,wBAAwB,CAAC;AAIxD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAMjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAOrD,UAAU,oBAAoB;IAC5B,aAAa,EAAE,qBAAqB,CAAC;IACrC,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAClH;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAqHlD,CAAC;AAIH,eAAe,eAAe,CAAC"}
|
|
@@ -8,7 +8,7 @@ import MaterialLibrary from "./MaterialLibrary.js";
|
|
|
8
8
|
// import type { AnimatedTransform } from "~/types/mesh";
|
|
9
9
|
import CreatedObject from "./CreatedObject.js";
|
|
10
10
|
import { useFrameEffects } from "../hooks/useFrameEffects.js";
|
|
11
|
-
const CustomPrimitive = memo(({ createdObject,
|
|
11
|
+
const CustomPrimitive = memo(({ createdObject, onObjectReady, handleObjectClick, }) => {
|
|
12
12
|
// const { handleObjectClick } = useSceneClick();
|
|
13
13
|
// console.log("Rendering CustomPrimitive with settings:", createdObject.name, createdObject);
|
|
14
14
|
const meshRef = useRef(null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectNode.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNode.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAA6D,cAAc,EAA0B,MAAM,wBAAwB,CAAC;AAEpL,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWrD,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAC7G,CAAC;AAkDF,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,
|
|
1
|
+
{"version":3,"file":"ObjectNode.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNode.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+B,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAA6D,cAAc,EAA0B,MAAM,wBAAwB,CAAC;AAEpL,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAWrD,KAAK,eAAe,GAAG;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,cAAc,EAAE,WAAW,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAC7G,CAAC;AAkDF,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAsJzC,CAAC;AAEF,eAAe,UAAU,CAAC"}
|
|
@@ -23,9 +23,9 @@ const ObjectNode = ({ node, cameraSettings, onObjectReady, handleObjectClick })
|
|
|
23
23
|
// Specialized renderers for each object type
|
|
24
24
|
const renderers = useMemo(() => ({
|
|
25
25
|
group: () => null,
|
|
26
|
-
mesh: (obj, cameraSettings, onObjectReady) => (_jsx(CustomPrimitive, { createdObject: obj,
|
|
27
|
-
model: (obj, cameraSettings, onObjectReady) => (_jsx(CustomPrimitive, { createdObject: obj,
|
|
28
|
-
custom_primitive: (obj, cameraSettings, onObjectReady) => (_jsx(CustomPrimitive, { createdObject: obj,
|
|
26
|
+
mesh: (obj, cameraSettings, onObjectReady) => (_jsx(CustomPrimitive, { createdObject: obj, onObjectReady: onObjectReady, handleObjectClick: handleObjectClick }, obj.id)),
|
|
27
|
+
model: (obj, cameraSettings, onObjectReady) => (_jsx(CustomPrimitive, { createdObject: obj, onObjectReady: onObjectReady, handleObjectClick: handleObjectClick }, obj.id)),
|
|
28
|
+
custom_primitive: (obj, cameraSettings, onObjectReady) => (_jsx(CustomPrimitive, { createdObject: obj, onObjectReady: onObjectReady, handleObjectClick: handleObjectClick }, obj.id)),
|
|
29
29
|
text: (obj, cameraSettings, onObjectReady) => {
|
|
30
30
|
const renderMode = obj.config?.renderMode ?? 'bitmap';
|
|
31
31
|
return (_jsx(CreatedObject, { createdObject: obj, onObjectReady: onObjectReady, handleObjectClick: handleObjectClick, children: renderMode === 'text3d'
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Object3D } from 'three';
|
|
3
|
+
import type { CameraState, CreatedObjectSettings } from '@ntalmagor/3drize-core';
|
|
4
|
+
import { type ThreeEvent } from '@react-three/fiber';
|
|
5
|
+
type ObjectNodeApiProps = {
|
|
6
|
+
objectId: string;
|
|
7
|
+
cameraSettings: CameraState;
|
|
8
|
+
onObjectReady?: (object: CreatedObjectSettings, ref: Object3D) => void;
|
|
9
|
+
handleObjectClick?: (object: CreatedObjectSettings, ref: Object3D, event: ThreeEvent<MouseEvent>) => void;
|
|
10
|
+
};
|
|
11
|
+
declare const ObjectNodeApi: React.FC<ObjectNodeApiProps>;
|
|
12
|
+
export default ObjectNodeApi;
|
|
13
|
+
//# sourceMappingURL=ObjectNodeApi.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectNodeApi.d.ts","sourceRoot":"","sources":["../../src/components/ObjectNodeApi.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,KAAK,EAAE,WAAW,EAAE,qBAAqB,EAAkB,MAAM,wBAAwB,CAAC;AACjG,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAKrD,KAAK,kBAAkB,GAAG;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,WAAW,CAAC;IAC5B,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;CAC7G,CAAC;AAEF,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,kBAAkB,CAoB/C,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useEffect, useState } from 'react';
|
|
3
|
+
// import { apiFetch } from '../utils/apiFetch';
|
|
4
|
+
import ObjectNode from './ObjectNode.js';
|
|
5
|
+
import { dataCenterServer } from '../constants.js';
|
|
6
|
+
const ObjectNodeApi = ({ objectId, cameraSettings, onObjectReady, handleObjectClick }) => {
|
|
7
|
+
const [node, setNode] = useState(null);
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
fetch(`${dataCenterServer}scene-objects/${objectId}/tree`)
|
|
10
|
+
.then(res => res.ok ? res.json() : Promise.reject(res.status))
|
|
11
|
+
.then(({ tree }) => setNode(tree))
|
|
12
|
+
.catch(err => console.error('Failed to fetch scene object tree:', err));
|
|
13
|
+
}, [objectId]);
|
|
14
|
+
if (!node)
|
|
15
|
+
return null;
|
|
16
|
+
return (_jsx(ObjectNode, { node: node, cameraSettings: cameraSettings, onObjectReady: onObjectReady, handleObjectClick: handleObjectClick }));
|
|
17
|
+
};
|
|
18
|
+
export default ObjectNodeApi;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Object3D } from 'three';
|
|
3
3
|
import { type ThreeEvent } from '@react-three/fiber';
|
|
4
|
-
import { GeneralObjectSettings, type CameraState, type CreatedObjectSettings } from '@ntalmagor/3drize-core';
|
|
4
|
+
import { AnimationSequence, GeneralObjectSettings, type CameraState, type CreatedObjectSettings } from '@ntalmagor/3drize-core';
|
|
5
5
|
interface ObjectsRendererProps {
|
|
6
6
|
cameraSettings: CameraState;
|
|
7
7
|
generalObjectSettings: GeneralObjectSettings;
|
|
8
8
|
createdObjects: CreatedObjectSettings[];
|
|
9
9
|
onObjectsReady?: () => void;
|
|
10
10
|
handleObjectClick?: (object: CreatedObjectSettings, ref: Object3D, event: ThreeEvent<MouseEvent>) => void;
|
|
11
|
+
sequences?: AnimationSequence[];
|
|
11
12
|
}
|
|
12
13
|
declare const ObjectsRenderer: React.FC<ObjectsRendererProps>;
|
|
13
14
|
export default ObjectsRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ObjectsRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ObjectsRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,EAAS,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAmB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"ObjectsRenderer.d.ts","sourceRoot":"","sources":["../../src/components/ObjectsRenderer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA6C,MAAM,OAAO,CAAC;AAClE,OAAO,EAAS,QAAQ,EAAE,MAAM,OAAO,CAAC;AACxC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAmB,qBAAqB,EAAe,KAAK,WAAW,EAAE,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAQ9J,UAAU,oBAAoB;IAC5B,cAAc,EAAE,WAAW,CAAC;IAC5B,qBAAqB,EAAE,qBAAqB,CAAC;IAC7C,cAAc,EAAE,qBAAqB,EAAE,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,IAAI,CAAC;IAC5B,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IAC1G,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,QAAA,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CA4DlD,CAAC;AAIH,eAAe,eAAe,CAAC"}
|
|
@@ -2,7 +2,8 @@ import { jsx as _jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { memo, useRef, useCallback, useMemo } from 'react';
|
|
3
3
|
import { buildObjectTree } from '@ntalmagor/3drize-core';
|
|
4
4
|
import ObjectNode from './ObjectNode.js';
|
|
5
|
-
|
|
5
|
+
import useInteraction from '../hooks/useInteraction.js';
|
|
6
|
+
const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSettings, onObjectsReady, handleObjectClick, sequences = [], }) => {
|
|
6
7
|
const groupRef = useRef(null);
|
|
7
8
|
const objectsTree = useMemo(() => buildObjectTree(createdObjects), [createdObjects]);
|
|
8
9
|
const readyObjectsCount = useRef(0);
|
|
@@ -13,7 +14,25 @@ const ObjectsRenderer = memo(({ cameraSettings, createdObjects, generalObjectSet
|
|
|
13
14
|
onObjectsReady && onObjectsReady();
|
|
14
15
|
}
|
|
15
16
|
}, [objectsTree.length, onObjectsReady]);
|
|
16
|
-
|
|
17
|
+
function filterInteractionsByEvent(interactions, mouseEvent) {
|
|
18
|
+
if (!interactions)
|
|
19
|
+
return [];
|
|
20
|
+
return interactions.filter((interaction) => interaction.mouseEvent === mouseEvent);
|
|
21
|
+
}
|
|
22
|
+
const { executeInteraction } = useInteraction({
|
|
23
|
+
cameraSettings,
|
|
24
|
+
sequences,
|
|
25
|
+
});
|
|
26
|
+
const handleObjectClickHandler = (createdObject, ref, event) => {
|
|
27
|
+
const clickInteractions = filterInteractionsByEvent(createdObject.interactions?.actions, "click");
|
|
28
|
+
clickInteractions.forEach((interaction) => {
|
|
29
|
+
executeInteraction({ interaction, ref, createdObject });
|
|
30
|
+
});
|
|
31
|
+
if (handleObjectClick) {
|
|
32
|
+
handleObjectClick(createdObject, ref, event);
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
return (_jsx("group", { ref: groupRef, name: "main-objects", position: generalObjectSettings.meshSettings.position, rotation: generalObjectSettings.meshSettings.rotation, scale: generalObjectSettings.meshSettings.scale, children: objectsTree.map(node => (_jsx(ObjectNode, { node: node, cameraSettings: cameraSettings, onObjectReady: onObjectReady, handleObjectClick: handleObjectClickHandler }, node.objectId))) }));
|
|
17
36
|
});
|
|
18
37
|
ObjectsRenderer.displayName = 'ObjectsRenderer';
|
|
19
38
|
export default ObjectsRenderer;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ProjectLoader.d.ts","sourceRoot":"","sources":["../../src/components/ProjectLoader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,OAAQ,EAAE,KAAK,qBAAqB,EAAkB,KAAK,WAAW,EAA2C,MAAM,wBAAwB,CAAC;AAIhJ,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ProjectLoader.d.ts","sourceRoot":"","sources":["../../src/components/ProjectLoader.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAKnD,OAAQ,EAAE,KAAK,qBAAqB,EAAkB,KAAK,WAAW,EAA2C,MAAM,wBAAwB,CAAC;AAIhJ,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAMrD,KAAK,YAAY,GAAG;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,CAAC,KAAK,IAAI,CAAC;IACtG,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,EAAE,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvE,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAChD,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IACvD,kBAAkB,CAAC,EAAE,MAAM,IAAI,CAAC;CACnC,CAAC;AAEF,QAAA,MAAM,aAAa,EAAE,KAAK,CAAC,EAAE,CAAC,YAAY,CAiHzC,CAAC;AAEF,eAAe,aAAa,CAAC"}
|
|
@@ -8,6 +8,9 @@ import { loadAssets } from "@ntalmagor/3drize-core";
|
|
|
8
8
|
import { buildQueryString } from "@ntalmagor/3drize-core";
|
|
9
9
|
import useMeshController from '../hooks/useMeshController.js';
|
|
10
10
|
import LoadingIndicator from "./LoadingIndicator.js";
|
|
11
|
+
// import type { HtmlElement } from "~/types/uiController";
|
|
12
|
+
const PROJECT_LOADER_SOURCE = 'projectLoader';
|
|
13
|
+
const PROJECT_LOADER_DEBUG_PREFIX = '[ProjectLoaderDebug]';
|
|
11
14
|
const ProjectLoader = ({ projectId, onObjectClick, onObjectHover, onElementClick, onElementHover, onSceneInitialized }) => {
|
|
12
15
|
const [project, setProject] = useState(null);
|
|
13
16
|
const meshController = useMeshController();
|
|
@@ -25,13 +28,26 @@ const ProjectLoader = ({ projectId, onObjectClick, onObjectHover, onElementClick
|
|
|
25
28
|
const loadProject = async (projectId, queryParams) => {
|
|
26
29
|
try {
|
|
27
30
|
const queryString = buildQueryString(queryParams);
|
|
28
|
-
const
|
|
31
|
+
const searchParams = new URLSearchParams(queryString);
|
|
32
|
+
searchParams.set('source', PROJECT_LOADER_SOURCE);
|
|
33
|
+
const url = `${dataCenterServer}projects/${projectId}?${searchParams.toString()}`;
|
|
34
|
+
console.log(PROJECT_LOADER_DEBUG_PREFIX, 'Fetching project', {
|
|
35
|
+
projectId,
|
|
36
|
+
queryParams,
|
|
37
|
+
url,
|
|
38
|
+
});
|
|
29
39
|
const response = await fetch(url, {
|
|
30
40
|
method: "GET",
|
|
31
41
|
headers: {
|
|
32
42
|
"Content-Type": "application/json",
|
|
33
43
|
},
|
|
34
44
|
});
|
|
45
|
+
console.log(PROJECT_LOADER_DEBUG_PREFIX, 'Received project response', {
|
|
46
|
+
projectId,
|
|
47
|
+
status: response.status,
|
|
48
|
+
ok: response.ok,
|
|
49
|
+
url,
|
|
50
|
+
});
|
|
35
51
|
if (!response.ok) {
|
|
36
52
|
if (response.status === 404) {
|
|
37
53
|
throw new Error("Project not found");
|
|
@@ -39,6 +55,11 @@ const ProjectLoader = ({ projectId, onObjectClick, onObjectHover, onElementClick
|
|
|
39
55
|
throw new Error(`HTTP error! status: ${response.status}`);
|
|
40
56
|
}
|
|
41
57
|
const responseData = await response.json();
|
|
58
|
+
console.log(PROJECT_LOADER_DEBUG_PREFIX, 'Parsed project payload', {
|
|
59
|
+
projectId,
|
|
60
|
+
sceneObjectsCount: responseData.sceneObjects?.length || 0,
|
|
61
|
+
projectName: responseData.name,
|
|
62
|
+
});
|
|
42
63
|
console.log("Loaded project:", responseData);
|
|
43
64
|
const sceneObjects = responseData.sceneObjects || [];
|
|
44
65
|
const modelObjects = sceneObjects.filter(obj => obj.type === 'model');
|
|
@@ -65,7 +86,10 @@ const ProjectLoader = ({ projectId, onObjectClick, onObjectHover, onElementClick
|
|
|
65
86
|
setProject(responseData);
|
|
66
87
|
}
|
|
67
88
|
catch (error) {
|
|
68
|
-
console.error(
|
|
89
|
+
console.error(PROJECT_LOADER_DEBUG_PREFIX, 'Error fetching project', {
|
|
90
|
+
projectId,
|
|
91
|
+
error,
|
|
92
|
+
});
|
|
69
93
|
}
|
|
70
94
|
};
|
|
71
95
|
if (!project) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SceneBuilder.d.ts","sourceRoot":"","sources":["../../src/components/SceneBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EAEV,iBAAiB,EAIlB,MAAM,wBAAwB,CAAC;AAWhC,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,
|
|
1
|
+
{"version":3,"file":"SceneBuilder.d.ts","sourceRoot":"","sources":["../../src/components/SceneBuilder.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAGnD,OAAO,KAAK,EAEV,iBAAiB,EAIlB,MAAM,wBAAwB,CAAC;AAWhC,QAAA,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CA0K7C,CAAC;AAEF,eAAe,YAAY,CAAC"}
|
|
@@ -10,7 +10,6 @@ import EnvironmentManager from "./EnvironmentManager.js";
|
|
|
10
10
|
import CameraController from "./CameraController.js";
|
|
11
11
|
import Ocean from "./Ocean.js";
|
|
12
12
|
import ObjectsRenderer from "./ObjectsRenderer.js";
|
|
13
|
-
import { useInteraction } from "../hooks/useInteraction.js";
|
|
14
13
|
const SceneBuilder = ({ project, width = "100%", height = "100vh", style = {}, className = "", onSceneInitialized, onUiElementClick, onObjectClick, }) => {
|
|
15
14
|
const sceneSettings = (project.sceneSettingsData || {});
|
|
16
15
|
const meshController = useMeshController();
|
|
@@ -84,24 +83,6 @@ const SceneBuilder = ({ project, width = "100%", height = "100vh", style = {}, c
|
|
|
84
83
|
onUiElementClick(element);
|
|
85
84
|
}
|
|
86
85
|
};
|
|
87
|
-
function filterInteractionsByEvent(interactions, mouseEvent) {
|
|
88
|
-
if (!interactions)
|
|
89
|
-
return [];
|
|
90
|
-
return interactions.filter((interaction) => interaction.mouseEvent === mouseEvent);
|
|
91
|
-
}
|
|
92
|
-
const { executeInteraction } = useInteraction({
|
|
93
|
-
cameraSettings: camera,
|
|
94
|
-
sequences: animationSequences,
|
|
95
|
-
});
|
|
96
|
-
const handleObjectClickHandler = (createdObject, ref, event) => {
|
|
97
|
-
const clickInteractions = filterInteractionsByEvent(createdObject.interactions?.actions, "click");
|
|
98
|
-
clickInteractions.forEach((interaction) => {
|
|
99
|
-
executeInteraction({ interaction, ref, createdObject });
|
|
100
|
-
});
|
|
101
|
-
if (onObjectClick) {
|
|
102
|
-
onObjectClick(createdObject, ref, event);
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
86
|
return (_jsx("div", { className: className, style: containerStyle, children: _jsx(Canvas, { style: {
|
|
106
87
|
backgroundColor: backgroundColor,
|
|
107
88
|
}, shadows: shadows, dpr: dpr, gl: {
|
|
@@ -121,6 +102,6 @@ const SceneBuilder = ({ project, width = "100%", height = "100vh", style = {}, c
|
|
|
121
102
|
if (onSceneInitialized) {
|
|
122
103
|
onSceneInitialized();
|
|
123
104
|
}
|
|
124
|
-
}, children: _jsxs(ProductionScene, { physicsSettings: physicsSettings, controls: controls, children: [_jsx(LightsManager, { lights: project.lights || [] }), _jsx(EnvironmentManager, { hdrSettings: environment.hdr, timeSettings: timeSettings, visible: true, sunSystemVisible: environment.sky.sunSystem.visible, sunSize: environment.sky.sunSystem.sunSize, moonSize: environment.sky.sunSystem.moonSize, sunIntensity: environment.sky.sunSystem.intensity, castShadow: environment.sky.sunSystem.castShadow, shadowMapSize: environment.sky.sunSystem.shadowMapSize, starsSettings: environment.stars, skyControllerSettings: environment.sky.visible && !environment.sky.sunSystem.visible ? environment.sky : undefined, cloudsSettings: environment.clouds, cloudsMaterialSettings: environment.clouds.materialSettings, rainSettings: environment.rain, fogSettings: environment.fog }), _jsx(CameraController, { settings: camera }), _jsx(Ocean, { settings: environment.ocean }), _jsx(ObjectsRenderer, { cameraSettings: camera, generalObjectSettings: generalObjectSettings, createdObjects: sceneObjects, onObjectsReady: undefined, handleObjectClick:
|
|
105
|
+
}, children: _jsxs(ProductionScene, { physicsSettings: physicsSettings, controls: controls, children: [_jsx(LightsManager, { lights: project.lights || [] }), _jsx(EnvironmentManager, { hdrSettings: environment.hdr, timeSettings: timeSettings, visible: true, sunSystemVisible: environment.sky.sunSystem.visible, sunSize: environment.sky.sunSystem.sunSize, moonSize: environment.sky.sunSystem.moonSize, sunIntensity: environment.sky.sunSystem.intensity, castShadow: environment.sky.sunSystem.castShadow, shadowMapSize: environment.sky.sunSystem.shadowMapSize, starsSettings: environment.stars, skyControllerSettings: environment.sky.visible && !environment.sky.sunSystem.visible ? environment.sky : undefined, cloudsSettings: environment.clouds, cloudsMaterialSettings: environment.clouds.materialSettings, rainSettings: environment.rain, fogSettings: environment.fog }), _jsx(CameraController, { settings: camera }), _jsx(Ocean, { settings: environment.ocean }), _jsx(ObjectsRenderer, { cameraSettings: camera, generalObjectSettings: generalObjectSettings, createdObjects: sceneObjects, onObjectsReady: undefined, sequences: animationSequences, handleObjectClick: onObjectClick ? (object, ref, event) => onObjectClick(object, ref, event) : undefined })] }) }) }));
|
|
125
106
|
};
|
|
126
107
|
export default SceneBuilder;
|
package/dist/constants.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const dataCenterServer
|
|
1
|
+
export declare const dataCenterServer: string;
|
|
2
2
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB,QAEG,CAAC"}
|
package/dist/constants.js
CHANGED
|
@@ -1 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
const LOCAL_DATA_CENTER_SERVER = 'http://localhost:3001/api/data/';
|
|
2
|
+
const PRODUCTION_DATA_CENTER_SERVER = 'https://3d-rise.com/api/data/';
|
|
3
|
+
const isLocalHostRuntime = typeof window !== 'undefined' &&
|
|
4
|
+
(window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1');
|
|
5
|
+
export const dataCenterServer = isLocalHostRuntime
|
|
6
|
+
? LOCAL_DATA_CENTER_SERVER
|
|
7
|
+
: PRODUCTION_DATA_CENTER_SERVER;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnimationEvents.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnimationEvents.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"useAnimationEvents.d.ts","sourceRoot":"","sources":["../../src/hooks/useAnimationEvents.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAUhF,UAAU,sBAAsB;IAC9B,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,aAAa,CAAC,EAAI,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,WAAW,CAAC,EAAM,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;IAClD,SAAS,CAAC,EAAQ,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;CACnD;AAED,eAAO,MAAM,kBAAkB,GAAI,UAAU,sBAAsB,SA0ClE,CAAC"}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react';
|
|
2
2
|
import { AnimationsManager } from '@ntalmagor/3drize-core';
|
|
3
|
+
const DEBUG_ANIMATION_EVENTS = false;
|
|
4
|
+
const debugLog = (...args) => {
|
|
5
|
+
if (DEBUG_ANIMATION_EVENTS) {
|
|
6
|
+
console.log('[useAnimationEvents]', ...args);
|
|
7
|
+
}
|
|
8
|
+
};
|
|
3
9
|
export const useAnimationEvents = (handlers) => {
|
|
4
10
|
const ref = useRef(handlers);
|
|
5
11
|
ref.current = handlers;
|
|
6
12
|
useEffect(() => {
|
|
7
|
-
|
|
13
|
+
debugLog('subscribing', {
|
|
14
|
+
sequenceStart: !!handlers.onSequenceStart,
|
|
15
|
+
sequenceEnd: !!handlers.onSequenceEnd,
|
|
16
|
+
stepStart: !!handlers.onStepStart,
|
|
17
|
+
stepEnd: !!handlers.onStepEnd,
|
|
18
|
+
});
|
|
19
|
+
const wrap = (key) => (event) => {
|
|
20
|
+
debugLog('event received', {
|
|
21
|
+
key,
|
|
22
|
+
sequenceId: event.sequenceId,
|
|
23
|
+
stepIndex: event.stepIndex,
|
|
24
|
+
transitionCount: event.step?.transitions?.length ?? 0,
|
|
25
|
+
});
|
|
26
|
+
ref.current[key]?.(event);
|
|
27
|
+
};
|
|
8
28
|
const ss = wrap('onSequenceStart');
|
|
9
29
|
const se = wrap('onSequenceEnd');
|
|
10
30
|
const ts = wrap('onStepStart');
|
|
@@ -18,6 +38,7 @@ export const useAnimationEvents = (handlers) => {
|
|
|
18
38
|
if (handlers.onStepEnd)
|
|
19
39
|
AnimationsManager.on('stepEnd', te);
|
|
20
40
|
return () => {
|
|
41
|
+
debugLog('unsubscribing');
|
|
21
42
|
AnimationsManager.off('sequenceStart', ss);
|
|
22
43
|
AnimationsManager.off('sequenceEnd', se);
|
|
23
44
|
AnimationsManager.off('stepStart', ts);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useObjectAnimation.d.ts","sourceRoot":"","sources":["../../src/hooks/useObjectAnimation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAY,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAwB,KAAK,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAyB,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"useObjectAnimation.d.ts","sourceRoot":"","sources":["../../src/hooks/useObjectAnimation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,EAAE,KAAK,qBAAqB,EAAY,MAAM,wBAAwB,CAAC;AAC9E,OAAO,EAAwB,KAAK,0BAA0B,EAAE,MAAM,wBAAwB,CAAC;AAC/F,OAAO,EAAyB,KAAK,2BAA2B,EAAE,MAAM,yBAAyB,CAAC;AAYlG,UAAU,yBAAyB;IACjC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,UAAU,wBAAyB,SAAQ,0BAA0B,EAAE,2BAA2B;CAAG;AAErG,eAAO,MAAM,kBAAkB,GAC7B,gBAAgB,qBAAqB,GAAG,IAAI,EAC5C,iBAAiB,OAAO,EACxB,UAAS,yBAA8B,EACvC,MAAM,QAAQ,KACb,wBAAwB,GAAG,IAiB7B,CAAC"}
|
|
@@ -1,11 +1,27 @@
|
|
|
1
1
|
import { findById } from '@ntalmagor/3drize-core';
|
|
2
2
|
import { useContinuousEffects } from "./useContinuousEffects.js";
|
|
3
3
|
import { useInteractionEffects } from "./useInteractionEffects.js";
|
|
4
|
+
import { useSequenceAnimation } from "./useSequenceAnimation.js";
|
|
5
|
+
const DEBUG_OBJECT_ANIMATION = false;
|
|
6
|
+
const debugLog = (...args) => {
|
|
7
|
+
if (DEBUG_OBJECT_ANIMATION) {
|
|
8
|
+
console.log('[useObjectAnimation]', ...args);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
4
11
|
export const useObjectAnimation = (objectSettings, animateMaterial, options = {}, ref) => {
|
|
5
12
|
const { enabled = true, hovered = false } = options;
|
|
6
13
|
const objectRef = ref || findById(objectSettings?.id);
|
|
14
|
+
debugLog('hook run', {
|
|
15
|
+
objectId: objectSettings?.id,
|
|
16
|
+
hasRefArg: !!ref,
|
|
17
|
+
resolvedObject: objectRef ? { name: objectRef.name, id: objectRef.userData?.id } : null,
|
|
18
|
+
enabled,
|
|
19
|
+
hovered,
|
|
20
|
+
animateMaterial,
|
|
21
|
+
});
|
|
7
22
|
// console.log(objectRef)
|
|
8
23
|
const continuousResult = useContinuousEffects(objectSettings, { enabled, animateMaterial, hovered }, objectRef);
|
|
9
24
|
const interactionResult = useInteractionEffects(objectSettings, { enabled, animateMaterial }, objectRef);
|
|
25
|
+
useSequenceAnimation(objectSettings?.id, objectRef);
|
|
10
26
|
return { ...continuousResult, ...interactionResult };
|
|
11
27
|
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Object3D } from 'three';
|
|
2
|
+
/**
|
|
3
|
+
* useSequenceAnimation
|
|
4
|
+
*
|
|
5
|
+
* Subscribes to AnimationsManager step events and, for each frame while a step
|
|
6
|
+
* is active, interpolates both transform AND material properties on the given
|
|
7
|
+
* object. Path-based transitions are delegated to usePathAnimation.
|
|
8
|
+
*
|
|
9
|
+
* Designed to be called inside useObjectAnimation so that AnimatedObject stays
|
|
10
|
+
* a thin group wrapper.
|
|
11
|
+
*/
|
|
12
|
+
export declare const useSequenceAnimation: (objectId: string | undefined, objectRef: Object3D | null | undefined) => void;
|
|
13
|
+
export default useSequenceAnimation;
|
|
14
|
+
//# sourceMappingURL=useSequenceAnimation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSequenceAnimation.d.ts","sourceRoot":"","sources":["../../src/hooks/useSequenceAnimation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AA0HtC;;;;;;;;;GASG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,MAAM,GAAG,SAAS,EAC5B,WAAW,QAAQ,GAAG,IAAI,GAAG,SAAS,SAuLvC,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import { useRef } from 'react';
|
|
2
|
+
import { useFrame } from '@react-three/fiber';
|
|
3
|
+
import { AnimationsManager, applySingleProperty, findById } from '@ntalmagor/3drize-core';
|
|
4
|
+
import { useAnimationEvents } from './useAnimationEvents.js';
|
|
5
|
+
import { usePathAnimation } from './usePathAnimation.js';
|
|
6
|
+
const DEBUG_SEQUENCE_ANIMATION = true;
|
|
7
|
+
const debugLog = (...args) => {
|
|
8
|
+
if (DEBUG_SEQUENCE_ANIMATION) {
|
|
9
|
+
console.log('[useSequenceAnimation]', ...args);
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
13
|
+
// Helpers
|
|
14
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
15
|
+
const TRANSFORM_KEYS = new Set(['position', 'rotation', 'scale', 'visible']);
|
|
16
|
+
function lerp(a, b, t) {
|
|
17
|
+
return a + (b - a) * t;
|
|
18
|
+
}
|
|
19
|
+
function lerpVec3(a, b, t) {
|
|
20
|
+
return [lerp(a[0], b[0], t), lerp(a[1], b[1], t), lerp(a[2], b[2], t)];
|
|
21
|
+
}
|
|
22
|
+
/** Parse a hex color string to [r, g, b] 0-1 */
|
|
23
|
+
function hexToRgb(hex) {
|
|
24
|
+
const h = hex.replace('#', '');
|
|
25
|
+
const n = parseInt(h.length === 3 ? h.split('').map(c => c + c).join('') : h, 16);
|
|
26
|
+
return [(n >> 16) / 255, ((n >> 8) & 0xff) / 255, (n & 0xff) / 255];
|
|
27
|
+
}
|
|
28
|
+
/** Lerp two hex color strings, returns a hex string */
|
|
29
|
+
function lerpColor(a, b, t) {
|
|
30
|
+
if (typeof a !== 'string' || typeof b !== 'string')
|
|
31
|
+
return b;
|
|
32
|
+
const [ar, ag, ab] = hexToRgb(a);
|
|
33
|
+
const [br, bg, bb] = hexToRgb(b);
|
|
34
|
+
const r = Math.round(lerp(ar, br, t) * 255);
|
|
35
|
+
const g = Math.round(lerp(ag, bg, t) * 255);
|
|
36
|
+
const bl = Math.round(lerp(ab, bb, t) * 255);
|
|
37
|
+
return `#${[r, g, bl].map(v => v.toString(16).padStart(2, '0')).join('')}`;
|
|
38
|
+
}
|
|
39
|
+
function lerpValue(a, b, t) {
|
|
40
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
41
|
+
return a.map((v, i) => typeof v === 'number' ? lerp(v, b[i] ?? v, t) : b[i]);
|
|
42
|
+
}
|
|
43
|
+
if (typeof a === 'number' && typeof b === 'number')
|
|
44
|
+
return lerp(a, b, t);
|
|
45
|
+
if (typeof a === 'string' && typeof b === 'string' && a.startsWith('#') && b.startsWith('#')) {
|
|
46
|
+
return lerpColor(a, b, t);
|
|
47
|
+
}
|
|
48
|
+
// Non-lerp-able — snap at t=1
|
|
49
|
+
return t >= 1 ? b : a;
|
|
50
|
+
}
|
|
51
|
+
/** Get material-related properties from a transition properties record */
|
|
52
|
+
function extractMaterialProps(props) {
|
|
53
|
+
if (!props)
|
|
54
|
+
return {};
|
|
55
|
+
return Object.fromEntries(Object.entries(props).filter(([k]) => !TRANSFORM_KEYS.has(k)));
|
|
56
|
+
}
|
|
57
|
+
/** Apply a material property to all materials on an object */
|
|
58
|
+
function applyMaterialProp(object, key, value) {
|
|
59
|
+
let appliedCount = 0;
|
|
60
|
+
object.traverse((child) => {
|
|
61
|
+
if (!child.material)
|
|
62
|
+
return;
|
|
63
|
+
const mats = Array.isArray(child.material) ? child.material : [child.material];
|
|
64
|
+
for (const mat of mats) {
|
|
65
|
+
if (!(key in mat) && !mat.uniforms?.[key])
|
|
66
|
+
continue;
|
|
67
|
+
if (key === 'opacity' && typeof value === 'number') {
|
|
68
|
+
// Opacity has no visible effect on many materials unless transparency is enabled.
|
|
69
|
+
if ('transparent' in mat) {
|
|
70
|
+
mat.transparent = value < 1;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
applySingleProperty(mat, key, value);
|
|
74
|
+
appliedCount += 1;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
debugLog('material property applied', { key, value, appliedCount, objectName: object.name, objectId: object.userData?.id });
|
|
78
|
+
}
|
|
79
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
80
|
+
// Hook
|
|
81
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
82
|
+
/**
|
|
83
|
+
* useSequenceAnimation
|
|
84
|
+
*
|
|
85
|
+
* Subscribes to AnimationsManager step events and, for each frame while a step
|
|
86
|
+
* is active, interpolates both transform AND material properties on the given
|
|
87
|
+
* object. Path-based transitions are delegated to usePathAnimation.
|
|
88
|
+
*
|
|
89
|
+
* Designed to be called inside useObjectAnimation so that AnimatedObject stays
|
|
90
|
+
* a thin group wrapper.
|
|
91
|
+
*/
|
|
92
|
+
export const useSequenceAnimation = (objectId, objectRef) => {
|
|
93
|
+
const { startPathAnimation, updatePathAnimation, stopPathAnimation, isAnimating: isPathAnimating } = usePathAnimation();
|
|
94
|
+
const resolveObject = () => {
|
|
95
|
+
const resolved = objectRef ?? (objectId ? findById(objectId) : null);
|
|
96
|
+
return resolved;
|
|
97
|
+
};
|
|
98
|
+
// Active step state. Null = no sequence step currently animating.
|
|
99
|
+
const stepRef = useRef(null);
|
|
100
|
+
// Progress 0-1; flips to 1 when done so useFrame short-circuits
|
|
101
|
+
const progressRef = useRef(1);
|
|
102
|
+
// ── Event listener ──────────────────────────────────────────────────────────
|
|
103
|
+
useAnimationEvents({
|
|
104
|
+
onStepStart: (event) => {
|
|
105
|
+
if (!objectId || !event.step?.transitions) {
|
|
106
|
+
debugLog('stepStart ignored: missing objectId or transitions', {
|
|
107
|
+
objectId,
|
|
108
|
+
hasTransitions: !!event.step?.transitions,
|
|
109
|
+
sequenceId: event.sequenceId,
|
|
110
|
+
stepIndex: event.stepIndex,
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
const resolvedObject = resolveObject();
|
|
115
|
+
debugLog('stepStart received', {
|
|
116
|
+
objectId,
|
|
117
|
+
sequenceId: event.sequenceId,
|
|
118
|
+
stepIndex: event.stepIndex,
|
|
119
|
+
transitionStates: event.step.transitions.map(t => t.state),
|
|
120
|
+
resolvedObject: resolvedObject ? {
|
|
121
|
+
name: resolvedObject.name,
|
|
122
|
+
id: resolvedObject.userData?.id,
|
|
123
|
+
} : null,
|
|
124
|
+
});
|
|
125
|
+
// Find the transition targeting this object
|
|
126
|
+
const transition = event.step.transitions.find(t => t.state === objectId);
|
|
127
|
+
if (!transition) {
|
|
128
|
+
debugLog('no matching transition for objectId', {
|
|
129
|
+
objectId,
|
|
130
|
+
availableStates: event.step.transitions.map(t => t.state),
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const d = event.step.duration || 1;
|
|
135
|
+
const ease = event.step.ease || 'linear';
|
|
136
|
+
const { properties, pathId = null } = transition;
|
|
137
|
+
debugLog('matched transition', {
|
|
138
|
+
objectId,
|
|
139
|
+
pathId,
|
|
140
|
+
duration: d,
|
|
141
|
+
ease,
|
|
142
|
+
fromKeys: Object.keys(properties.from || {}),
|
|
143
|
+
toKeys: Object.keys(properties.to || {}),
|
|
144
|
+
});
|
|
145
|
+
// Visibility shortcut
|
|
146
|
+
if (properties.to?.visible === false) {
|
|
147
|
+
if (resolvedObject)
|
|
148
|
+
resolvedObject.visible = false;
|
|
149
|
+
stepRef.current = null;
|
|
150
|
+
progressRef.current = 1;
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
if (resolvedObject)
|
|
154
|
+
resolvedObject.visible = true;
|
|
155
|
+
// Snapshot current object transform as defaults
|
|
156
|
+
const cur = resolvedObject;
|
|
157
|
+
const curPos = cur
|
|
158
|
+
? [cur.position.x, cur.position.y, cur.position.z]
|
|
159
|
+
: [0, 0, 0];
|
|
160
|
+
const curRot = cur
|
|
161
|
+
? [cur.rotation.x, cur.rotation.y, cur.rotation.z]
|
|
162
|
+
: [0, 0, 0];
|
|
163
|
+
const curSca = cur
|
|
164
|
+
? [cur.scale.x, cur.scale.y, cur.scale.z]
|
|
165
|
+
: [1, 1, 1];
|
|
166
|
+
const fp = properties.from;
|
|
167
|
+
const tp = properties.to;
|
|
168
|
+
stepRef.current = {
|
|
169
|
+
startTime: performance.now(),
|
|
170
|
+
duration: d,
|
|
171
|
+
ease,
|
|
172
|
+
fromPosition: (fp?.position ?? curPos),
|
|
173
|
+
toPosition: (tp?.position ?? curPos),
|
|
174
|
+
fromRotation: (fp?.rotation ?? curRot),
|
|
175
|
+
toRotation: (tp?.rotation ?? curRot),
|
|
176
|
+
fromScale: (fp?.scale ?? curSca),
|
|
177
|
+
toScale: (tp?.scale ?? curSca),
|
|
178
|
+
materialFrom: extractMaterialProps(fp),
|
|
179
|
+
materialTo: extractMaterialProps(tp),
|
|
180
|
+
visibilityOverride: null,
|
|
181
|
+
pathId,
|
|
182
|
+
};
|
|
183
|
+
progressRef.current = 0;
|
|
184
|
+
if (pathId) {
|
|
185
|
+
debugLog('starting path animation', { objectId, pathId, duration: d, ease });
|
|
186
|
+
startPathAnimation(pathId, d, { ease });
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
stopPathAnimation();
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
onStepEnd: (event) => {
|
|
193
|
+
debugLog('stepEnd received', {
|
|
194
|
+
objectId,
|
|
195
|
+
sequenceId: event.sequenceId,
|
|
196
|
+
stepIndex: event.stepIndex,
|
|
197
|
+
});
|
|
198
|
+
// Let useFrame finish the last frame at p=1 naturally; just clear step
|
|
199
|
+
// after a microtask so the final interpolated position is applied.
|
|
200
|
+
Promise.resolve().then(() => {
|
|
201
|
+
stepRef.current = null;
|
|
202
|
+
progressRef.current = 1;
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
});
|
|
206
|
+
// ── Per-frame interpolation ─────────────────────────────────────────────────
|
|
207
|
+
useFrame((_state, delta) => {
|
|
208
|
+
const resolvedObject = resolveObject();
|
|
209
|
+
if (progressRef.current >= 1 || !stepRef.current || !resolvedObject)
|
|
210
|
+
return;
|
|
211
|
+
const step = stepRef.current;
|
|
212
|
+
// Time-based progress drives property interpolation regardless of transform mode.
|
|
213
|
+
const p = AnimationsManager.getProgressFromTime(step.startTime, step.duration, step.ease);
|
|
214
|
+
progressRef.current = p;
|
|
215
|
+
// Path-based: delegate to usePathAnimation
|
|
216
|
+
if (step.pathId) {
|
|
217
|
+
const still = updatePathAnimation(delta, resolvedObject);
|
|
218
|
+
if (!still) {
|
|
219
|
+
progressRef.current = 1;
|
|
220
|
+
stepRef.current = null;
|
|
221
|
+
}
|
|
222
|
+
// Keep scale interpolation active while path controls position/rotation.
|
|
223
|
+
const sca = lerpVec3(step.fromScale, step.toScale, p);
|
|
224
|
+
resolvedObject.scale.set(...sca);
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
// — Transform —
|
|
228
|
+
const pos = lerpVec3(step.fromPosition, step.toPosition, p);
|
|
229
|
+
const rot = lerpVec3(step.fromRotation, step.toRotation, p);
|
|
230
|
+
const sca = lerpVec3(step.fromScale, step.toScale, p);
|
|
231
|
+
resolvedObject.position.set(...pos);
|
|
232
|
+
resolvedObject.rotation.set(...rot);
|
|
233
|
+
resolvedObject.scale.set(...sca);
|
|
234
|
+
}
|
|
235
|
+
if (p === 0 || p >= 0.99) {
|
|
236
|
+
debugLog('frame progress', {
|
|
237
|
+
objectId,
|
|
238
|
+
progress: p,
|
|
239
|
+
materialKeys: Object.keys(step.materialTo),
|
|
240
|
+
pathId: step.pathId,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
// — Material properties —
|
|
244
|
+
for (const key of Object.keys(step.materialTo)) {
|
|
245
|
+
const fromVal = step.materialFrom[key];
|
|
246
|
+
const toVal = step.materialTo[key];
|
|
247
|
+
if (fromVal === undefined && toVal === undefined)
|
|
248
|
+
continue;
|
|
249
|
+
const interpolated = lerpValue(fromVal ?? toVal, toVal, p);
|
|
250
|
+
applyMaterialProp(resolvedObject, key, interpolated);
|
|
251
|
+
}
|
|
252
|
+
if (p >= 1) {
|
|
253
|
+
progressRef.current = 1;
|
|
254
|
+
stepRef.current = null;
|
|
255
|
+
}
|
|
256
|
+
});
|
|
257
|
+
};
|
|
258
|
+
export default useSequenceAnimation;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ntalmagor/3drize-viewer",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.16",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,6 +38,6 @@
|
|
|
38
38
|
"typescript": "^5.7.2"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@ntalmagor/3drize-core": "^0.1.
|
|
41
|
+
"@ntalmagor/3drize-core": "^0.1.11"
|
|
42
42
|
}
|
|
43
43
|
}
|