@preference-sl/pref-viewer 2.11.0-beta.8 → 2.11.0

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.
@@ -1,5 +1,4 @@
1
- import { AdvancedDynamicTexture } from "@babylonjs/gui";
2
- import { OpeningAnimationMenu } from "./babylonjs-animation-opening-menu.js";
1
+ import OpeningAnimationMenu from "./babylonjs-animation-opening-menu.js";
3
2
 
4
3
  /**
5
4
  * OpeningAnimation - Manages open/close animations for a model part (e.g., a door) in a Babylon.js scene.
@@ -13,13 +12,14 @@ import { OpeningAnimationMenu } from "./babylonjs-animation-opening-menu.js";
13
12
  * - Manages the animation control menu (OpeningAnimationMenu) and its callbacks.
14
13
  *
15
14
  * Public Methods:
15
+ * - dispose(): Disposes the OpeningAnimation instance and releases all associated resources.
16
16
  * - isAnimationForNode(node): Checks if the animation affects the given node.
17
17
  * - playOpen(): Starts the opening animation.
18
18
  * - playClose(): Starts the closing animation.
19
19
  * - pause(): Pauses the current animation.
20
20
  * - goToOpened(): Moves animation to the fully opened state.
21
21
  * - goToClosed(): Moves animation to the fully closed state.
22
- * - showControls(advancedDynamicTexture): Displays the animation control menu.
22
+ * - showControls(canvas): Displays the animation control menu.
23
23
  * - hideControls(): Hides the animation control menu.
24
24
  * - isControlsVisible(): Returns true if the control menu is visible for this animation.
25
25
  *
@@ -39,16 +39,8 @@ import { OpeningAnimationMenu } from "./babylonjs-animation-opening-menu.js";
39
39
  * - #checkProgress(progress): Applies threshold logic to progress.
40
40
  * - #updateControlsSlider(): Updates the slider in the control menu.
41
41
  * - #updateControls(): Updates all controls in the menu.
42
- *
43
- * Usage Example:
44
- * const anim = new OpeningAnimation("door", openGroup, closeGroup);
45
- * anim.playOpen();
46
- * anim.pause();
47
- * anim.goToClosed();
48
- * anim.showControls(adt);
49
- * anim.hideControls();
50
42
  */
51
- export class OpeningAnimation {
43
+ export default class OpeningAnimation {
52
44
  static states = {
53
45
  paused: 0,
54
46
  closed: 1,
@@ -57,21 +49,26 @@ export class OpeningAnimation {
57
49
  closing: 4,
58
50
  };
59
51
 
52
+ name = "";
60
53
  #openAnimation = null;
61
54
  #closeAnimation = null;
62
-
63
55
  #nodes = [];
56
+ #menu = null;
57
+
64
58
  #state = OpeningAnimation.states.closed;
65
59
  #lastPausedFrame = 0;
66
60
  #startFrame = 0;
67
61
  #endFrame = 0;
68
62
  #speedRatio = 1.0;
69
63
  #loop = false;
70
-
71
- #advancedDynamicTexture = null;
72
- #menu = null;
73
64
  #progressThreshold = 0.025;
74
65
 
66
+ #handlers = {
67
+ onOpened: null,
68
+ onClosed: null,
69
+ updateControlsSlider: null,
70
+ };
71
+
75
72
  /**
76
73
  * Creates a new OpeningAnimation instance for managing open/close animations of a model part.
77
74
  * @param {string} name - The identifier for this animation (e.g., door name).
@@ -95,8 +92,15 @@ export class OpeningAnimation {
95
92
  this.#speedRatio = this.#openAnimation.speedRatio || 1.0;
96
93
 
97
94
  this.#getNodesFromAnimationGroups();
98
- this.#openAnimation.onAnimationGroupEndObservable.add(this.#onOpened.bind(this));
99
- this.#closeAnimation.onAnimationGroupEndObservable.add(this.#onClosed.bind(this));
95
+ this.#bindHandlers();
96
+ this.#openAnimation.onAnimationGroupEndObservable.add(this.#handlers.onOpened);
97
+ this.#closeAnimation.onAnimationGroupEndObservable.add(this.#handlers.onClosed);
98
+ }
99
+
100
+ #bindHandlers() {
101
+ this.#handlers.onOpened = this.#onOpened.bind(this);
102
+ this.#handlers.onClosed = this.#onClosed.bind(this);
103
+ this.#handlers.updateControlsSlider = this.#updateControlsSlider.bind(this);
100
104
  }
101
105
 
102
106
  /**
@@ -138,13 +142,18 @@ export class OpeningAnimation {
138
142
  #goToOpened(useLoop = false) {
139
143
  this.#lastPausedFrame = this.#endFrame;
140
144
 
141
- if (this.#openAnimation._isStarted && !this.#openAnimation._isPaused) {
145
+ if (this.#openAnimation._isStarted && !this.#openAnimation._isPaused){
142
146
  this.#openAnimation.pause();
143
147
  }
144
- this.#openAnimation.goToFrame(this.#endFrame);
148
+ this.#openAnimation.goToFrame(this.#endFrame);
145
149
 
146
- this.#closeAnimation.pause();
147
- this.#closeAnimation.goToFrame(this.#startFrame);
150
+ if (this.#closeAnimation._isStarted && this.#closeAnimation._isPaused) {
151
+ this.#closeAnimation.goToFrame(this.#startFrame);
152
+ } else {
153
+ this.#closeAnimation.start();
154
+ this.#closeAnimation.pause();
155
+ this.#closeAnimation.goToFrame(this.#startFrame);
156
+ }
148
157
 
149
158
  this.#state = OpeningAnimation.states.opened;
150
159
  this.#updateControls();
@@ -167,8 +176,13 @@ export class OpeningAnimation {
167
176
  }
168
177
  this.#closeAnimation.goToFrame(this.#endFrame - this.#startFrame);
169
178
 
170
- this.#openAnimation.pause();
171
- this.#openAnimation.goToFrame(this.#startFrame);
179
+ if (this.#openAnimation._isStarted && this.#openAnimation._isPaused) {
180
+ this.#openAnimation.goToFrame(this.#startFrame);
181
+ } else {
182
+ this.#openAnimation.start();
183
+ this.#openAnimation.pause();
184
+ this.#openAnimation.goToFrame(this.#startFrame);
185
+ }
172
186
 
173
187
  this.#state = OpeningAnimation.states.closed;
174
188
  this.#updateControls();
@@ -303,6 +317,25 @@ export class OpeningAnimation {
303
317
  * ---------------------------
304
318
  */
305
319
 
320
+ /**
321
+ * Disposes the OpeningAnimation instance and releases all associated resources.
322
+ * @public
323
+ * @returns {void}
324
+ */
325
+ dispose() {
326
+ this.hideControls();
327
+ if (this.#openAnimation) {
328
+ this.#openAnimation.onAnimationGroupEndObservable.removeCallback(this.#handlers.onOpened);
329
+ this.#openAnimation = null;
330
+ }
331
+ if (this.#closeAnimation) {
332
+ this.#closeAnimation.onAnimationGroupEndObservable.removeCallback(this.#handlers.onClosed);
333
+ this.#closeAnimation = null;
334
+ }
335
+ this.#nodes = [];
336
+ this.name = "";
337
+ }
338
+
306
339
  /**
307
340
  * Checks if the animation affects the given node.
308
341
  * @param {string} node - Node identifier.
@@ -320,6 +353,7 @@ export class OpeningAnimation {
320
353
  if (this.#state === OpeningAnimation.states.opening || this.#state === OpeningAnimation.states.opened) {
321
354
  return;
322
355
  }
356
+
323
357
  if (this.#state === OpeningAnimation.states.closing) {
324
358
  this.#lastPausedFrame = this.#endFrame - this.#closeAnimation.getCurrentFrame();
325
359
  this.#closeAnimation.pause();
@@ -344,6 +378,7 @@ export class OpeningAnimation {
344
378
  if (this.#state === OpeningAnimation.states.closing || this.#state === OpeningAnimation.states.closed) {
345
379
  return;
346
380
  }
381
+
347
382
  if (this.#state === OpeningAnimation.states.opening) {
348
383
  this.#lastPausedFrame = this.#openAnimation.getCurrentFrame();
349
384
  this.#openAnimation.pause();
@@ -397,11 +432,9 @@ export class OpeningAnimation {
397
432
  * Displays the animation control menu and sets up callbacks.
398
433
  * Synchronizes slider and button states with animation.
399
434
  * @public
400
- * @param {AdvancedDynamicTexture} advancedDynamicTexture - Babylon.js GUI texture.
435
+ * @param {HTMLCanvasElement} canvas - The canvas element for rendering.
401
436
  */
402
- showControls(advancedDynamicTexture) {
403
- this.#advancedDynamicTexture = advancedDynamicTexture;
404
- this.#advancedDynamicTexture.metadata = { animationName: this.name };
437
+ showControls(canvas) {
405
438
  const controlCallbacks = {
406
439
  onGoToOpened: () => {
407
440
  if (this.#state === OpeningAnimation.states.opened) {
@@ -449,10 +482,10 @@ export class OpeningAnimation {
449
482
  this.#menu.animationLoop = this.#loop;
450
483
  },
451
484
  };
452
- this.#menu = new OpeningAnimationMenu(this.#advancedDynamicTexture, this.#state, this.#getProgress(), this.#loop, controlCallbacks);
485
+ this.#menu = new OpeningAnimationMenu(this.name, canvas, this.#state, this.#getProgress(), this.#loop, controlCallbacks);
453
486
 
454
487
  // Attach to Babylon.js scene render loop for real-time updates
455
- this.#openAnimation._scene.onBeforeRenderObservable.add(this.#updateControlsSlider.bind(this));
488
+ this.#openAnimation._scene.onBeforeRenderObservable.add(this.#handlers.updateControlsSlider);
456
489
  }
457
490
 
458
491
  /**
@@ -463,10 +496,9 @@ export class OpeningAnimation {
463
496
  if (!this.isControlsVisible()) {
464
497
  return;
465
498
  }
466
- // Remove the observer when controls are hidden
467
- this.#openAnimation._scene.onBeforeRenderObservable.removeCallback(this.#updateControlsSlider.bind(this));
468
- this.#advancedDynamicTexture.dispose();
469
- this.#advancedDynamicTexture = null;
499
+ this.#openAnimation?._scene?.onBeforeRenderObservable.removeCallback(this.#handlers.updateControlsSlider);
500
+ this.#menu.dispose();
501
+ this.#menu = null;
470
502
  }
471
503
 
472
504
  /**
@@ -475,7 +507,7 @@ export class OpeningAnimation {
475
507
  * @returns {boolean} True if controls are visible for this animation; otherwise, false.
476
508
  */
477
509
  isControlsVisible() {
478
- return !!(this.#advancedDynamicTexture && this.#advancedDynamicTexture.metadata?.animationName === this.name && this.#menu);
510
+ return !!(this.#menu?.isVisible);
479
511
  }
480
512
 
481
513
  /**
@@ -489,7 +521,6 @@ export class OpeningAnimation {
489
521
  * @public
490
522
  * @returns {number}
491
523
  */
492
-
493
524
  get state() {
494
525
  return this.#state;
495
526
  }