@3driseai/3drise-viewer 0.1.24 → 0.1.26

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.
Files changed (133) hide show
  1. package/dist/animationsV2/ClipPlayer.d.ts +13 -0
  2. package/dist/animationsV2/ClipPlayer.d.ts.map +1 -0
  3. package/dist/animationsV2/ClipPlayer.js +140 -0
  4. package/dist/animationsV2/ClipsRuntime.d.ts +111 -0
  5. package/dist/animationsV2/ClipsRuntime.d.ts.map +1 -0
  6. package/dist/animationsV2/ClipsRuntime.js +476 -0
  7. package/dist/animationsV2/appliers.d.ts +16 -0
  8. package/dist/animationsV2/appliers.d.ts.map +1 -0
  9. package/dist/animationsV2/appliers.js +204 -0
  10. package/dist/animationsV2/clipUtils.d.ts +33 -0
  11. package/dist/animationsV2/clipUtils.d.ts.map +1 -0
  12. package/dist/animationsV2/clipUtils.js +164 -0
  13. package/dist/animationsV2/elementSettings.d.ts +15 -0
  14. package/dist/animationsV2/elementSettings.d.ts.map +1 -0
  15. package/dist/animationsV2/elementSettings.js +16 -0
  16. package/dist/animationsV2/index.d.ts +16 -0
  17. package/dist/animationsV2/index.d.ts.map +1 -0
  18. package/dist/animationsV2/index.js +12 -0
  19. package/dist/animationsV2/nodeTracks.d.ts +13 -0
  20. package/dist/animationsV2/nodeTracks.d.ts.map +1 -0
  21. package/dist/animationsV2/nodeTracks.js +165 -0
  22. package/dist/animationsV2/normalize.d.ts +4 -0
  23. package/dist/animationsV2/normalize.d.ts.map +1 -0
  24. package/dist/animationsV2/normalize.js +49 -0
  25. package/dist/animationsV2/sequenceUtils.d.ts +57 -0
  26. package/dist/animationsV2/sequenceUtils.d.ts.map +1 -0
  27. package/dist/animationsV2/sequenceUtils.js +120 -0
  28. package/dist/animationsV2/types.d.ts +95 -0
  29. package/dist/animationsV2/types.d.ts.map +1 -0
  30. package/dist/animationsV2/types.js +8 -0
  31. package/dist/api/sceneHandle.d.ts +102 -0
  32. package/dist/api/sceneHandle.d.ts.map +1 -0
  33. package/dist/api/sceneHandle.js +237 -0
  34. package/dist/components/CameraController.d.ts.map +1 -1
  35. package/dist/components/CameraController.js +3 -44
  36. package/dist/components/Clouds.d.ts.map +1 -1
  37. package/dist/components/Clouds.js +0 -34
  38. package/dist/components/CreatedObject.d.ts.map +1 -1
  39. package/dist/components/CreatedObject.js +19 -1
  40. package/dist/components/EnvironmentManager.d.ts.map +1 -1
  41. package/dist/components/EnvironmentManager.js +6 -4
  42. package/dist/components/ObjectNode.d.ts.map +1 -1
  43. package/dist/components/ObjectNode.js +5 -1
  44. package/dist/components/ObjectsRenderer.d.ts +5 -1
  45. package/dist/components/ObjectsRenderer.d.ts.map +1 -1
  46. package/dist/components/ObjectsRenderer.js +24 -3
  47. package/dist/components/Ocean.d.ts.map +1 -1
  48. package/dist/components/Ocean.js +0 -63
  49. package/dist/components/ProjectLoader.d.ts +9 -3
  50. package/dist/components/ProjectLoader.d.ts.map +1 -1
  51. package/dist/components/ProjectLoader.js +5 -4
  52. package/dist/components/SceneBuilder.d.ts +9 -1
  53. package/dist/components/SceneBuilder.d.ts.map +1 -1
  54. package/dist/components/SceneBuilder.js +30 -5
  55. package/dist/components/SkyController.d.ts.map +1 -1
  56. package/dist/components/SkyController.js +0 -39
  57. package/dist/components/Stars.d.ts.map +1 -1
  58. package/dist/components/Stars.js +3 -46
  59. package/dist/components/terrain/TerrainSurface.d.ts.map +1 -1
  60. package/dist/components/terrain/TerrainSurface.js +0 -5
  61. package/dist/components/volumetricClouds/VolumetricCloudsPass.d.ts.map +1 -1
  62. package/dist/components/volumetricClouds/VolumetricCloudsPass.js +0 -6
  63. package/dist/hooks/index.d.ts +2 -2
  64. package/dist/hooks/index.d.ts.map +1 -1
  65. package/dist/hooks/index.js +2 -2
  66. package/dist/hooks/useInteraction.d.ts +7 -7
  67. package/dist/hooks/useInteraction.d.ts.map +1 -1
  68. package/dist/hooks/useInteraction.js +87 -233
  69. package/dist/hooks/useLightConfig.d.ts.map +1 -1
  70. package/dist/hooks/useLightConfig.js +7 -0
  71. package/dist/hooks/useLightLive.d.ts.map +1 -1
  72. package/dist/hooks/useLightLive.js +2 -0
  73. package/dist/hooks/useLightTargets.d.ts +7 -0
  74. package/dist/hooks/useLightTargets.d.ts.map +1 -0
  75. package/dist/hooks/useLightTargets.js +132 -0
  76. package/dist/hooks/useObjectAnimation.d.ts.map +1 -1
  77. package/dist/hooks/useObjectAnimation.js +0 -2
  78. package/dist/hooks/useOceanMaterial.d.ts.map +1 -1
  79. package/dist/hooks/useOceanMaterial.js +0 -5
  80. package/dist/hooks/useRuntimeSettings.d.ts +15 -0
  81. package/dist/hooks/useRuntimeSettings.d.ts.map +1 -0
  82. package/dist/hooks/useRuntimeSettings.js +22 -0
  83. package/dist/hooks/useSequenceAnimation.d.ts.map +1 -1
  84. package/dist/hooks/useSequenceAnimation.js +27 -9
  85. package/dist/index.d.ts +6 -1
  86. package/dist/index.d.ts.map +1 -1
  87. package/dist/index.js +5 -0
  88. package/dist/interactions/index.d.ts +3 -0
  89. package/dist/interactions/index.d.ts.map +1 -0
  90. package/dist/interactions/index.js +1 -0
  91. package/dist/interactions/runner.d.ts +9 -0
  92. package/dist/interactions/runner.d.ts.map +1 -0
  93. package/dist/interactions/runner.js +23 -0
  94. package/dist/operations/catalogue/displayImage.d.ts +3 -0
  95. package/dist/operations/catalogue/displayImage.d.ts.map +1 -0
  96. package/dist/operations/catalogue/displayImage.js +39 -0
  97. package/dist/operations/catalogue/fade.d.ts +3 -0
  98. package/dist/operations/catalogue/fade.d.ts.map +1 -0
  99. package/dist/operations/catalogue/fade.js +44 -0
  100. package/dist/operations/catalogue/focus.d.ts +3 -0
  101. package/dist/operations/catalogue/focus.d.ts.map +1 -0
  102. package/dist/operations/catalogue/focus.js +22 -0
  103. package/dist/operations/catalogue/glow.d.ts +3 -0
  104. package/dist/operations/catalogue/glow.d.ts.map +1 -0
  105. package/dist/operations/catalogue/glow.js +49 -0
  106. package/dist/operations/catalogue/materialFx.d.ts +6 -0
  107. package/dist/operations/catalogue/materialFx.d.ts.map +1 -0
  108. package/dist/operations/catalogue/materialFx.js +13 -0
  109. package/dist/operations/catalogue/moveToFront.d.ts +3 -0
  110. package/dist/operations/catalogue/moveToFront.d.ts.map +1 -0
  111. package/dist/operations/catalogue/moveToFront.js +25 -0
  112. package/dist/operations/catalogue/visibility.d.ts +3 -0
  113. package/dist/operations/catalogue/visibility.d.ts.map +1 -0
  114. package/dist/operations/catalogue/visibility.js +24 -0
  115. package/dist/operations/catalogue/zoom.d.ts +3 -0
  116. package/dist/operations/catalogue/zoom.d.ts.map +1 -0
  117. package/dist/operations/catalogue/zoom.js +32 -0
  118. package/dist/operations/index.d.ts +5 -0
  119. package/dist/operations/index.d.ts.map +1 -0
  120. package/dist/operations/index.js +4 -0
  121. package/dist/operations/registry.d.ts +11 -0
  122. package/dist/operations/registry.d.ts.map +1 -0
  123. package/dist/operations/registry.js +21 -0
  124. package/dist/operations/runtime.d.ts +22 -0
  125. package/dist/operations/runtime.d.ts.map +1 -0
  126. package/dist/operations/runtime.js +161 -0
  127. package/dist/operations/types.d.ts +96 -0
  128. package/dist/operations/types.d.ts.map +1 -0
  129. package/dist/operations/types.js +3 -0
  130. package/dist/operations/useOperationsRuntime.d.ts +3 -0
  131. package/dist/operations/useOperationsRuntime.d.ts.map +1 -0
  132. package/dist/operations/useOperationsRuntime.js +31 -0
  133. package/package.json +2 -2
@@ -0,0 +1,4 @@
1
+ import type { AnimationClip, AnimationSequence } from './types';
2
+ export declare function normalizeClip(row: any): AnimationClip;
3
+ export declare function normalizeSequence(row: any): AnimationSequence;
4
+ //# sourceMappingURL=normalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.d.ts","sourceRoot":"","sources":["../../src/animationsV2/normalize.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAkB,MAAM,SAAS,CAAC;AAKhF,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,GAAG,aAAa,CAarD;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,GAAG,GAAG,iBAAiB,CAgC7D"}
@@ -0,0 +1,49 @@
1
+ import { DEFAULT_DRIVER_SETTINGS } from './types.js';
2
+ const DRIVERS = ['time', 'mouseWheel', 'mouseX', 'mouseY'];
3
+ export function normalizeClip(row) {
4
+ return {
5
+ id: row.id,
6
+ name: row.name ?? 'Clip',
7
+ key: row.key ?? '',
8
+ description: row.description ?? undefined,
9
+ duration: Number(row.duration) || 4,
10
+ fps: Number(row.fps) || 30,
11
+ loop: !!row.loop,
12
+ yoyo: !!row.yoyo,
13
+ endMode: row.endMode === 'restore' ? 'restore' : 'hold',
14
+ tracks: Array.isArray(row.tracks) ? row.tracks : [],
15
+ };
16
+ }
17
+ export function normalizeSequence(row) {
18
+ const steps = Array.isArray(row.steps) ? row.steps : [];
19
+ return {
20
+ id: row.id,
21
+ name: row.name ?? 'Sequence',
22
+ key: row.key ?? '',
23
+ description: row.description ?? undefined,
24
+ steps: steps.map((s, i) => ({
25
+ id: s?.id ?? `step-${i}`,
26
+ clips: Array.isArray(s?.clips)
27
+ ? s.clips
28
+ .filter((c) => c && typeof c.clipId === 'string')
29
+ .map((c, j) => ({
30
+ id: c.id ?? `sc-${i}-${j}`,
31
+ clipId: c.clipId,
32
+ delay: Math.max(0, Number(c.delay) || 0),
33
+ speed: Number(c.speed) > 0 ? Number(c.speed) : 1,
34
+ }))
35
+ : [],
36
+ })),
37
+ loop: !!row.loop,
38
+ yoyo: !!row.yoyo,
39
+ reverse: !!row.reverse,
40
+ endMode: row.endMode === 'restore' ? 'restore' : 'hold',
41
+ driver: DRIVERS.includes(row.driver) ? row.driver : 'time',
42
+ driverSettings: {
43
+ sensitivity: Number(row.driverSettings?.sensitivity) > 0 ? Number(row.driverSettings.sensitivity) : DEFAULT_DRIVER_SETTINGS.sensitivity,
44
+ smoothing: Number(row.driverSettings?.smoothing) >= 0 ? Number(row.driverSettings.smoothing) : DEFAULT_DRIVER_SETTINGS.smoothing,
45
+ invert: !!row.driverSettings?.invert,
46
+ },
47
+ autoplay: !!row.autoplay,
48
+ };
49
+ }
@@ -0,0 +1,57 @@
1
+ import type { AnimationClip, AnimationSequence, StepClip } from './types';
2
+ export interface ScheduledClip {
3
+ /** `${stepClip.id}` — stable across re-resolves of the same sequence. */
4
+ id: string;
5
+ stepIndex: number;
6
+ /** Row within the step. */
7
+ row: number;
8
+ stepClip: StepClip;
9
+ clip: AnimationClip;
10
+ /** Sequence seconds. */
11
+ start: number;
12
+ end: number;
13
+ }
14
+ export interface SequenceSchedule {
15
+ /** In priority order (schedule index = activation order). */
16
+ entries: ScheduledClip[];
17
+ steps: {
18
+ start: number;
19
+ end: number;
20
+ }[];
21
+ duration: number;
22
+ }
23
+ export type ClipLookup = ReadonlyMap<string, AnimationClip> | ((id: string) => AnimationClip | undefined);
24
+ export declare const clipMap: (clips: readonly AnimationClip[]) => Map<string, AnimationClip>;
25
+ /** Step clips whose clip is missing (deleted, not loaded) are skipped. */
26
+ export declare function resolveSequence(seq: AnimationSequence, clips: ClipLookup): SequenceSchedule;
27
+ /** Clip-local time (seconds, 0..clip.duration) of an entry at sequence time T. */
28
+ export declare function entryLocalTime(entry: ScheduledClip, T: number): number;
29
+ /**
30
+ * Whether an entry writes at sequence time T: from its start on, and after its end
31
+ * only if its clip holds ('hold'); a 'restore' clip lets go at its end.
32
+ */
33
+ export declare function isEntryActive(entry: ScheduledClip, T: number): boolean;
34
+ export interface StepConflict {
35
+ stepIndex: number;
36
+ /** The upper row — its animation is hidden while the other drives the property. */
37
+ masked: StepClip;
38
+ /** The lower row — it wins. */
39
+ winner: StepClip;
40
+ state: string;
41
+ node?: string;
42
+ path: string;
43
+ }
44
+ /**
45
+ * Same-step clips that drive the same property at the same time. A pair conflicts
46
+ * when the upper row is still ANIMATING while the lower row is active (animating,
47
+ * or holding its end value) — then the lower row hides it. An upper row that only
48
+ * holds under a lower one animating is the expected override, not a conflict.
49
+ */
50
+ export declare function findSequenceConflicts(seq: AnimationSequence, clips: ClipLookup): StepConflict[];
51
+ /** Step-clip ids involved in any conflict (row markers). */
52
+ export declare function conflictedStepClipIds(conflicts: readonly StepConflict[]): Set<string>;
53
+ export declare function newSequence(name: string, key: string): AnimationSequence;
54
+ export declare function newStepClip(clipId: string): StepClip;
55
+ /** Deep copy with fresh ids (duplicate). */
56
+ export declare function cloneSequence(seq: AnimationSequence, name: string, key: string): AnimationSequence;
57
+ //# sourceMappingURL=sequenceUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sequenceUtils.d.ts","sourceRoot":"","sources":["../../src/animationsV2/sequenceUtils.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAI1E,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,QAAQ,CAAC;IACnB,IAAI,EAAE,aAAa,CAAC;IACpB,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,gBAAgB;IAC/B,6DAA6D;IAC7D,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,KAAK,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,MAAM,KAAK,aAAa,GAAG,SAAS,CAAC,CAAC;AAK1G,eAAO,MAAM,OAAO,GAAI,OAAO,SAAS,aAAa,EAAE,KAAG,GAAG,CAAC,MAAM,EAAE,aAAa,CAC/C,CAAC;AAKrC,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,UAAU,GAAG,gBAAgB,CAqB3F;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAGtE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAGtE;AAID,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,MAAM,EAAE,QAAQ,CAAC;IACjB,+BAA+B;IAC/B,MAAM,EAAE,QAAQ,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd;AAID;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,UAAU,GAAG,YAAY,EAAE,CAuC/F;AAED,4DAA4D;AAC5D,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,SAAS,YAAY,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAIrF;AAID,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB,CAMxE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,QAAQ,CAEpD;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,GAAG,EAAE,iBAAiB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB,CASlG"}
@@ -0,0 +1,120 @@
1
+ import { DEFAULT_DRIVER_SETTINGS } from './types.js';
2
+ import { uid } from './clipUtils.js';
3
+ const lookup = (clips, id) => (typeof clips === 'function' ? clips(id) : clips.get(id));
4
+ export const clipMap = (clips) => new Map(clips.map(c => [c.id, c]));
5
+ const safeSpeed = (s) => (Number.isFinite(s) && s > 0 ? s : 1);
6
+ const safeDelay = (d) => (Number.isFinite(d) && d > 0 ? d : 0);
7
+ /** Step clips whose clip is missing (deleted, not loaded) are skipped. */
8
+ export function resolveSequence(seq, clips) {
9
+ const entries = [];
10
+ const steps = [];
11
+ let cursor = 0;
12
+ seq.steps.forEach((step, stepIndex) => {
13
+ const stepStart = cursor;
14
+ let stepEnd = stepStart;
15
+ step.clips.forEach((stepClip, row) => {
16
+ const clip = lookup(clips, stepClip.clipId);
17
+ if (!clip)
18
+ return;
19
+ const start = stepStart + safeDelay(stepClip.delay);
20
+ const end = start + Math.max(0, clip.duration) / safeSpeed(stepClip.speed);
21
+ entries.push({ id: stepClip.id, stepIndex, row, stepClip, clip, start, end });
22
+ stepEnd = Math.max(stepEnd, end);
23
+ });
24
+ steps.push({ start: stepStart, end: stepEnd });
25
+ cursor = stepEnd;
26
+ });
27
+ return { entries, steps, duration: cursor };
28
+ }
29
+ /** Clip-local time (seconds, 0..clip.duration) of an entry at sequence time T. */
30
+ export function entryLocalTime(entry, T) {
31
+ const local = (T - entry.start) * safeSpeed(entry.stepClip.speed);
32
+ return Math.min(entry.clip.duration, Math.max(0, local));
33
+ }
34
+ /**
35
+ * Whether an entry writes at sequence time T: from its start on, and after its end
36
+ * only if its clip holds ('hold'); a 'restore' clip lets go at its end.
37
+ */
38
+ export function isEntryActive(entry, T) {
39
+ if (T < entry.start)
40
+ return false;
41
+ return T <= entry.end || entry.clip.endMode !== 'restore';
42
+ }
43
+ const targetKey = (state, node, path) => `${state}|${node ?? ''}|${path}`;
44
+ /**
45
+ * Same-step clips that drive the same property at the same time. A pair conflicts
46
+ * when the upper row is still ANIMATING while the lower row is active (animating,
47
+ * or holding its end value) — then the lower row hides it. An upper row that only
48
+ * holds under a lower one animating is the expected override, not a conflict.
49
+ */
50
+ export function findSequenceConflicts(seq, clips) {
51
+ const { entries } = resolveSequence(seq, clips);
52
+ const out = [];
53
+ const byStep = new Map();
54
+ entries.forEach(e => {
55
+ const list = byStep.get(e.stepIndex) ?? [];
56
+ list.push(e);
57
+ byStep.set(e.stepIndex, list);
58
+ });
59
+ for (const [stepIndex, list] of byStep) {
60
+ for (let i = 0; i < list.length; i++) {
61
+ const upper = list[i];
62
+ if (upper.end <= upper.start)
63
+ continue; // nothing animates
64
+ const upperTargets = new Map();
65
+ upper.clip.tracks.forEach(t => {
66
+ if (!t.muted && t.keys.length)
67
+ upperTargets.set(targetKey(t.state, t.node, t.path), t);
68
+ });
69
+ if (!upperTargets.size)
70
+ continue;
71
+ for (let j = i + 1; j < list.length; j++) {
72
+ const lower = list[j];
73
+ const lowerEnd = lower.clip.endMode === 'restore' ? lower.end : Infinity;
74
+ const overlaps = upper.start < lowerEnd && lower.start < upper.end;
75
+ if (!overlaps)
76
+ continue;
77
+ const seen = new Set();
78
+ lower.clip.tracks.forEach(t => {
79
+ if (t.muted || !t.keys.length)
80
+ return;
81
+ const k = targetKey(t.state, t.node, t.path);
82
+ const hit = upperTargets.get(k);
83
+ if (!hit || seen.has(k))
84
+ return;
85
+ seen.add(k);
86
+ out.push({ stepIndex, masked: upper.stepClip, winner: lower.stepClip, state: hit.state, node: hit.node, path: hit.path });
87
+ });
88
+ }
89
+ }
90
+ }
91
+ return out;
92
+ }
93
+ /** Step-clip ids involved in any conflict (row markers). */
94
+ export function conflictedStepClipIds(conflicts) {
95
+ const ids = new Set();
96
+ conflicts.forEach(c => { ids.add(c.masked.id); ids.add(c.winner.id); });
97
+ return ids;
98
+ }
99
+ // --- builders ----------------------------------------------------------------------
100
+ export function newSequence(name, key) {
101
+ return {
102
+ id: uid('seq'), name, key, steps: [{ id: uid('step'), clips: [] }],
103
+ loop: false, yoyo: false, reverse: false, endMode: 'hold',
104
+ driver: 'time', driverSettings: { ...DEFAULT_DRIVER_SETTINGS }, autoplay: false,
105
+ };
106
+ }
107
+ export function newStepClip(clipId) {
108
+ return { id: uid('sc'), clipId, delay: 0, speed: 1 };
109
+ }
110
+ /** Deep copy with fresh ids (duplicate). */
111
+ export function cloneSequence(seq, name, key) {
112
+ return {
113
+ ...seq,
114
+ id: uid('seq'),
115
+ name,
116
+ key,
117
+ isDirty: undefined,
118
+ steps: seq.steps.map(s => ({ id: uid('step'), clips: s.clips.map(c => ({ ...c, id: uid('sc') })) })),
119
+ };
120
+ }
@@ -0,0 +1,95 @@
1
+ /** Easing of the segment leaving a key. Names match core's easingUtils, plus 'step'. */
2
+ export type EaseName = 'linear' | 'step' | 'easeInQuad' | 'easeOutQuad' | 'easeInOutQuad' | 'easeInCubic' | 'easeOutCubic' | 'easeInOutCubic' | 'easeInQuart' | 'easeOutQuart' | 'easeInOutQuart' | 'easeInSine' | 'easeOutSine' | 'easeInOutSine' | 'easeInExpo' | 'easeOutExpo' | 'easeInOutExpo' | 'easeInBack' | 'easeOutBack' | 'easeInOutBack' | 'easeOutElastic' | 'easeOutBounce';
3
+ export type KeyValue = number | number[] | string | boolean;
4
+ export interface Keyframe {
5
+ /** Stable within the track — selection and drag follow it, not the index. */
6
+ id: string;
7
+ /** Seconds from clip start. */
8
+ t: number;
9
+ value: KeyValue;
10
+ /** Easing of the segment LEAVING this key. */
11
+ ease?: EaseName;
12
+ }
13
+ export interface Track {
14
+ id: string;
15
+ /** Object id, or 'camera'. (sky / clouds / ocean come later.) */
16
+ state: string;
17
+ /**
18
+ * A node inside a `model` object (its ModelTree key: the node name). When set,
19
+ * `path` is relative to that node: 'position' | 'rotation' | 'scale' | 'visible' |
20
+ * 'material.<color|opacity|roughness|metalness|emissive|emissiveIntensity>' —
21
+ * the same fields a node override (config.nodeOverrides) carries.
22
+ */
23
+ node?: string;
24
+ /** Settings path on that element ('meshSettings.position', 'materialSettings.opacity', 'config.intensity'…), or node-relative when `node` is set. */
25
+ path: string;
26
+ /** Sorted by t. */
27
+ keys: Keyframe[];
28
+ muted?: boolean;
29
+ }
30
+ export interface AnimationClip {
31
+ id: string;
32
+ name: string;
33
+ key: string;
34
+ description?: string;
35
+ /** Seconds. */
36
+ duration: number;
37
+ /** Timeline frame rate — display and snapping only; playback samples real time. */
38
+ fps: number;
39
+ loop: boolean;
40
+ yoyo: boolean;
41
+ /** When a non-looping clip finishes: keep the last values, or return to authored. */
42
+ endMode: 'hold' | 'restore';
43
+ tracks: Track[];
44
+ /** Unsaved changes (save bookkeeping, never sent). */
45
+ isDirty?: boolean;
46
+ }
47
+ /** One clip inside a step. Plays once, forward — loop / yoyo / reverse are the sequence's. */
48
+ export interface StepClip {
49
+ id: string;
50
+ /** AnimationClip id. */
51
+ clipId: string;
52
+ /** Seconds after the step starts (>= 0). */
53
+ delay: number;
54
+ /** 1 = authored speed. */
55
+ speed: number;
56
+ }
57
+ /** Clips that start together. The step ends when its longest clip ends; then the next step starts. */
58
+ export interface SequenceStep {
59
+ id: string;
60
+ clips: StepClip[];
61
+ }
62
+ /** What moves a sequence's clock: time (it plays), or an input that scrubs it. */
63
+ export type SequenceDriver = 'time' | 'mouseWheel' | 'mouseX' | 'mouseY';
64
+ export interface SequenceDriverSettings {
65
+ /** mouseWheel: progress per wheel pixel is sensitivity / 1000 (1 ≈ one long scroll for the whole sequence). */
66
+ sensitivity: number;
67
+ /** 0 = follows the input exactly; higher = eases toward it (≈ seconds to settle). */
68
+ smoothing: number;
69
+ /** Flip the direction: right-to-left, bottom-to-top, wheel up = forward. */
70
+ invert: boolean;
71
+ }
72
+ export declare const DEFAULT_DRIVER_SETTINGS: SequenceDriverSettings;
73
+ export interface AnimationSequence {
74
+ id: string;
75
+ name: string;
76
+ key: string;
77
+ description?: string;
78
+ /** Run in order. */
79
+ steps: SequenceStep[];
80
+ /** Whole-sequence playback. */
81
+ loop: boolean;
82
+ yoyo: boolean;
83
+ reverse: boolean;
84
+ endMode: 'hold' | 'restore';
85
+ /** What moves the clock. Input drivers scrub the sequence instead of playing it. */
86
+ driver: SequenceDriver;
87
+ driverSettings: SequenceDriverSettings;
88
+ /** Start when the project loads (published viewer; the studio never autoplays). */
89
+ autoplay: boolean;
90
+ /** Unsaved changes (save bookkeeping, never sent). */
91
+ isDirty?: boolean;
92
+ }
93
+ export declare const DEFAULT_EASE: EaseName;
94
+ export declare const FPS_PRESETS: readonly [24, 25, 30, 60];
95
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/animationsV2/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ // =============================================================================
2
+ // Animations V2 — timeline clips and sequences (project docs
3
+ // claude/animations-v2-design.md, claude/animations-v2-sequences-plan.md).
4
+ // Shared by the studio (client) and the published viewer (ProjectLoader).
5
+ // =============================================================================
6
+ export const DEFAULT_DRIVER_SETTINGS = { sensitivity: 1, smoothing: 0.25, invert: false };
7
+ export const DEFAULT_EASE = 'easeInOutCubic';
8
+ export const FPS_PRESETS = [24, 25, 30, 60];
@@ -0,0 +1,102 @@
1
+ import type { ActionSequence } from '@3driseai/3drise-core';
2
+ import type { AnimationClip, AnimationSequence } from '../animationsV2/types';
3
+ export interface SceneActionInfo {
4
+ id: string;
5
+ key?: string;
6
+ name: string;
7
+ description?: string;
8
+ applied: boolean;
9
+ }
10
+ export interface SceneClipInfo {
11
+ id: string;
12
+ key: string;
13
+ name: string;
14
+ description?: string;
15
+ /** Seconds, one pass. */
16
+ duration: number;
17
+ loop: boolean;
18
+ yoyo: boolean;
19
+ endMode: 'hold' | 'restore';
20
+ playing: boolean;
21
+ }
22
+ export interface SceneSequenceInfo {
23
+ id: string;
24
+ key: string;
25
+ name: string;
26
+ description?: string;
27
+ /** Seconds, one pass through every step. */
28
+ duration: number;
29
+ steps: number;
30
+ loop: boolean;
31
+ yoyo: boolean;
32
+ reverse: boolean;
33
+ endMode: 'hold' | 'restore';
34
+ /** 'time' plays; 'mouseWheel' | 'mouseX' | 'mouseY' — the input scrubs it once played. */
35
+ driver: 'time' | 'mouseWheel' | 'mouseX' | 'mouseY';
36
+ autoplay: boolean;
37
+ playing: boolean;
38
+ }
39
+ export interface ScenePlayOptions {
40
+ /** Playback rate, 1 = authored. */
41
+ speed?: number;
42
+ /** Play backwards. For a sequence this overrides its own `reverse` for this run. */
43
+ reverse?: boolean;
44
+ /** Where to start, 0–1 of the duration. */
45
+ from?: number;
46
+ }
47
+ /** The same controls for clips and for sequences. */
48
+ export interface ScenePlayback<Info> {
49
+ list(): Info[];
50
+ play(ref: string, options?: ScenePlayOptions): boolean;
51
+ pause(ref: string): boolean;
52
+ resume(ref: string): boolean;
53
+ /** Stop and put everything it animated back to the authored scene. */
54
+ stop(ref: string): boolean;
55
+ /** Jump to a point, 0–1 of the duration. */
56
+ seek(ref: string, progress: number): boolean;
57
+ isPlaying(ref: string): boolean;
58
+ }
59
+ export type SceneHandleEventType = 'actionApplied' | 'actionReverted' | 'animationStart' | 'animationEnd' | 'animationLoop';
60
+ export interface SceneHandleEvent {
61
+ type: SceneHandleEventType;
62
+ kind: 'action' | 'clip' | 'sequence';
63
+ id: string;
64
+ key?: string;
65
+ name: string;
66
+ }
67
+ export interface SceneHandle {
68
+ actions: {
69
+ list(): SceneActionInfo[];
70
+ apply(ref: string): boolean;
71
+ revert(ref: string): boolean;
72
+ /** Returns true when it applied, false when it reverted (or the action was not found). */
73
+ toggle(ref: string): boolean;
74
+ isApplied(ref: string): boolean;
75
+ /** Revert every applied action of this project — back to the authored scene. */
76
+ reset(): void;
77
+ };
78
+ clips: ScenePlayback<SceneClipInfo>;
79
+ sequences: ScenePlayback<SceneSequenceInfo> & {
80
+ /**
81
+ * Drive a sequence from your own input (page scroll, a slider…): its position,
82
+ * 0–1 along its own direction. A running input-driven sequence eases there with
83
+ * its smoothing; otherwise it is posed there at once.
84
+ */
85
+ setProgress(ref: string, progress: number): boolean;
86
+ /** Current position, 0–1 along its own direction. */
87
+ getProgress(ref: string): number;
88
+ };
89
+ /** Subscribe to this project's action / clip / sequence events. Returns the unsubscribe. */
90
+ on(type: SceneHandleEventType, listener: (event: SceneHandleEvent) => void): () => void;
91
+ }
92
+ export interface SceneHandleSource {
93
+ actions: ActionSequence[];
94
+ clips: AnimationClip[];
95
+ sequences: AnimationSequence[];
96
+ }
97
+ /**
98
+ * Build a handle over one project's actions, clips and sequences. `getSource` is
99
+ * read on every call, so the handle stays valid if the project data is replaced.
100
+ */
101
+ export declare function createSceneHandle(getSource: () => SceneHandleSource): SceneHandle;
102
+ //# sourceMappingURL=sceneHandle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sceneHandle.d.ts","sourceRoot":"","sources":["../../src/api/sceneHandle.ts"],"names":[],"mappings":"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"}