@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.
- package/package.json +61 -50
- package/src/babylonjs-animation-controller.js +58 -76
- package/src/babylonjs-animation-opening-menu.js +189 -154
- package/src/babylonjs-animation-opening.js +67 -36
- package/src/babylonjs-controller.js +233 -113
- package/src/file-storage.js +11 -2
- package/src/index.js +18 -866
- package/src/panzoom-controller.js +92 -55
- package/src/pref-viewer-2d.js +15 -3
- package/src/pref-viewer-3d-data.js +3 -2
- package/src/pref-viewer-3d.js +11 -4
- package/src/pref-viewer-dialog.js +71 -46
- package/src/pref-viewer-task.js +1 -1
- package/src/pref-viewer.js +934 -0
- package/src/styles.js +334 -0
- package/src/svg-resolver.js +23 -0
|
@@ -1,23 +1,36 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
1
|
+
import OpeningAnimation from "./babylonjs-animation-opening.js";
|
|
2
|
+
import { PrefViewer3DAnimationMenuStyles } from "./styles.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* OpeningAnimationMenu - Manages and renders the animation control menu for opening/closing animations in a Babylon.js scene.
|
|
5
|
+
* OpeningAnimationMenu - Manages and renders the interactive animation control menu for opening/closing animations in a Babylon.js scene.
|
|
6
6
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
7
|
+
* Summary:
|
|
8
|
+
* Provides a floating HTML-based GUI menu with playback and loop controls for animated nodes, including buttons and a progress slider.
|
|
9
|
+
* Handles user interaction, updates UI state based on animation state, and invokes external callbacks for animation actions.
|
|
10
|
+
* Designed for integration with Babylon.js product configurators and interactive 3D applications.
|
|
11
|
+
*
|
|
12
|
+
* Key Features:
|
|
13
|
+
* - Renders a menu with buttons for controlling animation playback (open, close, pause, go to opened/closed, loop).
|
|
9
14
|
* - Updates button states and slider position based on animation state, progress, and loop mode.
|
|
10
15
|
* - Handles user interactions and invokes provided callbacks for animation actions.
|
|
11
16
|
* - Synchronizes the slider value with animation progress, avoiding callback loops.
|
|
17
|
+
* - Provides setters to update animation state, progress, and loop mode from external controllers.
|
|
18
|
+
* - Disposes and cleans up all DOM resources when no longer needed.
|
|
12
19
|
*
|
|
13
20
|
* Public Setters:
|
|
14
21
|
* - set animationState(state): Updates the animation state and button states.
|
|
15
22
|
* - set animationProgress(progress): Updates the animation progress and slider value.
|
|
16
23
|
* - set animationLoop(loop): Updates the loop mode and loop button states.
|
|
17
24
|
*
|
|
25
|
+
* Public Methods:
|
|
26
|
+
* - dispose(): Disposes the animation menu and releases all associated DOM resources.
|
|
27
|
+
*
|
|
28
|
+
* Public Getters:
|
|
29
|
+
* - isVisible: Returns whether the animation menu is currently visible in the DOM.
|
|
30
|
+
*
|
|
18
31
|
* Private Methods:
|
|
19
32
|
* - #createMenu(): Initializes and renders the menu UI.
|
|
20
|
-
* - #addButton(name,
|
|
33
|
+
* - #addButton(name, imageSVG, enabled, active, visible, callback): Adds a button to the menu with specified properties.
|
|
21
34
|
* - #createButtons(): Creates all control buttons and sets their initial states.
|
|
22
35
|
* - #getButtonByName(name): Retrieves a button control by its name.
|
|
23
36
|
* - #setButtonState(name, enabled, active, visible): Updates the visual state of a button.
|
|
@@ -27,9 +40,10 @@ import { OpeningAnimation } from "./babylonjs-animation-opening.js";
|
|
|
27
40
|
* - #setPlayerButtonsState(): Updates all playback control buttons.
|
|
28
41
|
* - #setLoopButtonsState(): Updates all loop control buttons.
|
|
29
42
|
* - #createSlider(): Creates and configures the animation progress slider.
|
|
43
|
+
* - #onSliderInput(event): Handles the slider input event for animation progress.
|
|
30
44
|
*
|
|
31
45
|
* Usage Example:
|
|
32
|
-
* const menu = new OpeningAnimationMenu(
|
|
46
|
+
* const menu = new OpeningAnimationMenu(name, canvas, state, progress, loop, {
|
|
33
47
|
* onOpen: () => { ... },
|
|
34
48
|
* onClose: () => { ... },
|
|
35
49
|
* onPause: () => { ... },
|
|
@@ -42,51 +56,45 @@ import { OpeningAnimation } from "./babylonjs-animation-opening.js";
|
|
|
42
56
|
* menu.animationProgress = 0.5;
|
|
43
57
|
* menu.animationLoop = true;
|
|
44
58
|
*/
|
|
45
|
-
export class OpeningAnimationMenu {
|
|
59
|
+
export default class OpeningAnimationMenu {
|
|
46
60
|
#animationState = OpeningAnimation.states.closed;
|
|
47
61
|
#animationProgress = 0;
|
|
48
62
|
#animationLoop = false;
|
|
49
63
|
#callbacks = null;
|
|
50
64
|
|
|
51
|
-
|
|
52
|
-
#
|
|
53
|
-
#
|
|
54
|
-
#
|
|
65
|
+
#name = "";
|
|
66
|
+
#canvas = null;
|
|
67
|
+
#containerMain = null;
|
|
68
|
+
#containerButtons = null;
|
|
55
69
|
#slider = null;
|
|
56
70
|
|
|
57
|
-
// Style properties
|
|
58
|
-
#buttonSize = 28;
|
|
59
|
-
#buttonLoopPaddingLeft = 3;
|
|
60
|
-
#colorActive = "#6BA53A";
|
|
61
|
-
#colorEnabled = "#333333";
|
|
62
|
-
#colorDisabled = "#777777";
|
|
63
|
-
#colorIcon = "#FFFFFF";
|
|
64
|
-
#colorBorder = "#FFFFFF";
|
|
65
|
-
#sliderThumbWidth = 20;
|
|
66
|
-
#sliderBarOffset = 10;
|
|
67
71
|
#icon = {
|
|
68
|
-
close: `<svg id="play-backwards" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
69
|
-
closed: `<svg id="skip-backward" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
70
|
-
open: `<svg id="play" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
71
|
-
opened: `<svg id="skip-forward" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
72
|
-
pause: `<svg id="pause" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
73
|
-
repeat: `<svg id="repeat" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
74
|
-
repeatOff: `<svg id="repeat-off" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path
|
|
72
|
+
close: `<svg id="play-backwards" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M16,18.86V4.86l-11,7,11,7Z"/></svg>`,
|
|
73
|
+
closed: `<svg id="skip-backward" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M20,5V19L13,12M6,5V19H4V5M13,5V19L6,12"/></svg>`,
|
|
74
|
+
open: `<svg id="play" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M8,5.14v14l11-7-11-7Z"/></svg>`,
|
|
75
|
+
opened: `<svg id="skip-forward" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M4,5V19L11,12M18,5V19H20V5M11,5V19L18,12"/></svg>`,
|
|
76
|
+
pause: `<svg id="pause" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M14,19H18V5H14M6,19H10V5H6V19Z"/></svg>`,
|
|
77
|
+
repeat: `<svg id="repeat" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M17,17H7V14L3,18L7,22V19H19V13H17M7,7H17V10L21,6L17,2V5H5V11H7V7Z"/></svg>`,
|
|
78
|
+
repeatOff: `<svg id="repeat-off" width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M2,5.27L3.28,4L20,20.72L18.73,22L15.73,19H7V22L3,18L7,14V17H13.73L7,10.27V11H5V8.27L2,5.27M17,13H19V17.18L17,15.18V13M17,5V2L21,6L17,10V7H8.82L6.82,5H17Z"/></svg>`,
|
|
75
79
|
};
|
|
76
80
|
|
|
77
|
-
#
|
|
81
|
+
#handler = {
|
|
82
|
+
onSliderInput: null,
|
|
83
|
+
};
|
|
78
84
|
|
|
79
85
|
/**
|
|
80
86
|
* Constructs the OpeningAnimationMenu and initializes the menu UI.
|
|
81
|
-
* @param {
|
|
87
|
+
* @param {string} name - The name of the animation.
|
|
88
|
+
* @param {HTMLCanvasElement} canvas - The canvas element for rendering.
|
|
82
89
|
* @param {number} animationState - Current animation state (enum).
|
|
83
90
|
* @param {number} animationProgress - Current animation progress (0 to 1).
|
|
84
91
|
* @param {boolean} animationLoop - Whether the animation is set to loop.
|
|
85
92
|
* @param {object} callbacks - Callback functions for menu actions (play, pause, open, close, etc.).
|
|
86
93
|
* @public
|
|
87
94
|
*/
|
|
88
|
-
constructor(
|
|
89
|
-
this.#
|
|
95
|
+
constructor(name, canvas, animationState, animationProgress, animationLoop, callbacks) {
|
|
96
|
+
this.#name = name;
|
|
97
|
+
this.#canvas = canvas;
|
|
90
98
|
this.#animationState = animationState;
|
|
91
99
|
this.#animationProgress = animationProgress;
|
|
92
100
|
this.#animationLoop = animationLoop;
|
|
@@ -95,29 +103,6 @@ export class OpeningAnimationMenu {
|
|
|
95
103
|
this.#createMenu(animationState);
|
|
96
104
|
}
|
|
97
105
|
|
|
98
|
-
/**
|
|
99
|
-
* Initializes and renders the menu UI, including buttons and slider.
|
|
100
|
-
* @private
|
|
101
|
-
*/
|
|
102
|
-
#createMenu() {
|
|
103
|
-
if (!this.#advancedDynamicTexture) {
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
this.#mainPanel = new StackPanel();
|
|
107
|
-
this.#mainPanel.isVertical = true;
|
|
108
|
-
this.#secondaryPanel = new StackPanel();
|
|
109
|
-
this.#secondaryPanel.isVertical = false;
|
|
110
|
-
this.#secondaryPanel.height = `${this.#buttonSize}px`;
|
|
111
|
-
this.#mainPanel.addControl(this.#secondaryPanel);
|
|
112
|
-
|
|
113
|
-
this.#advancedDynamicTexture.addControl(this.#mainPanel);
|
|
114
|
-
this.#mainPanel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
|
|
115
|
-
this.#mainPanel.verticalAlignment = Control.VERTICAL_ALIGNMENT_BOTTOM;
|
|
116
|
-
|
|
117
|
-
this.#createButtons();
|
|
118
|
-
this.#createSlider();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
106
|
/**
|
|
122
107
|
* Internal helper to add a button to the menu.
|
|
123
108
|
* Sets button appearance and attaches the callback for user interaction.
|
|
@@ -129,25 +114,21 @@ export class OpeningAnimationMenu {
|
|
|
129
114
|
* @param {boolean} visible - Whether the button is visible.
|
|
130
115
|
* @param {function} callback - Callback to invoke on button click.
|
|
131
116
|
*/
|
|
132
|
-
#addButton(name,
|
|
133
|
-
const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
};
|
|
142
|
-
const button = Button.CreateImageOnlyButton(`button_animation_${name}`, imageURL);
|
|
143
|
-
Object.assign(button, buttonProps);
|
|
144
|
-
button.image.stretch = Image.STRETCH_UNIFORM;
|
|
145
|
-
button.onPointerUpObservable.add(() => {
|
|
117
|
+
#addButton(name, imageSVG, enabled = true, active = false, visible = true, callback) {
|
|
118
|
+
const stateClass = active ? "active" : enabled ? "enabled" : "disabled";
|
|
119
|
+
const visibilityClass = visible ? "visible" : "hidden";
|
|
120
|
+
|
|
121
|
+
const button = document.createElement("button");
|
|
122
|
+
button.classList.add(stateClass, visibilityClass);
|
|
123
|
+
button.setAttribute("name", `button_animation_${name}`);
|
|
124
|
+
button.innerHTML = imageSVG;
|
|
125
|
+
button.addEventListener("click", (event) => {
|
|
146
126
|
if (callback && typeof callback === "function") {
|
|
147
127
|
callback();
|
|
148
128
|
}
|
|
149
129
|
});
|
|
150
|
-
|
|
130
|
+
|
|
131
|
+
this.#containerButtons.appendChild(button);
|
|
151
132
|
}
|
|
152
133
|
|
|
153
134
|
/**
|
|
@@ -156,19 +137,54 @@ export class OpeningAnimationMenu {
|
|
|
156
137
|
*/
|
|
157
138
|
#createButtons() {
|
|
158
139
|
const buttonsState = this.#getButtonsState();
|
|
159
|
-
this.#addButton("closed",
|
|
160
|
-
this.#addButton("close",
|
|
161
|
-
this.#addButton("pause",
|
|
162
|
-
this.#addButton("open",
|
|
163
|
-
this.#addButton("opened",
|
|
164
|
-
this.#addButton("repeat",
|
|
165
|
-
this.#addButton("repeatOff",
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
140
|
+
this.#addButton("closed", this.#icon.closed, buttonsState.closed.enabled, buttonsState.closed.active, buttonsState.closed.visible, this.#callbacks.onGoToClosed);
|
|
141
|
+
this.#addButton("close", this.#icon.close, buttonsState.close.enabled, buttonsState.close.active, buttonsState.close.visible, this.#callbacks.onClose);
|
|
142
|
+
this.#addButton("pause", this.#icon.pause, buttonsState.pause.enabled, buttonsState.pause.active, buttonsState.pause.visible, this.#callbacks.onPause);
|
|
143
|
+
this.#addButton("open", this.#icon.open, buttonsState.open.enabled, buttonsState.open.active, buttonsState.open.visible, this.#callbacks.onOpen);
|
|
144
|
+
this.#addButton("opened", this.#icon.opened, buttonsState.opened.enabled, buttonsState.opened.active, buttonsState.opened.visible, this.#callbacks.onGoToOpened);
|
|
145
|
+
this.#addButton("repeat", this.#icon.repeat, buttonsState.repeat.enabled, buttonsState.repeat.active, buttonsState.repeat.visible, this.#callbacks.onToggleLoop);
|
|
146
|
+
this.#addButton("repeatOff", this.#icon.repeatOff, buttonsState.repeatOff.enabled, buttonsState.repeatOff.active, buttonsState.repeatOff.visible, this.#callbacks.onToggleLoop);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Creates and configures the animation progress slider.
|
|
151
|
+
* @private
|
|
152
|
+
*/
|
|
153
|
+
#createSlider() {
|
|
154
|
+
this.#slider = document.createElement("input");
|
|
155
|
+
this.#slider.setAttribute("type", "range");
|
|
156
|
+
this.#slider.setAttribute("min", "0");
|
|
157
|
+
this.#slider.setAttribute("max", "1");
|
|
158
|
+
this.#slider.setAttribute("step", "0.01");
|
|
159
|
+
this.#slider.setAttribute("value", this.#animationProgress.toString());
|
|
160
|
+
this.#slider.classList.add("animation-menu-slider");
|
|
161
|
+
this.#handler.onSliderInput = this.#onSliderInput.bind(this);
|
|
162
|
+
this.#slider.addEventListener("input", this.#handler.onSliderInput);
|
|
163
|
+
|
|
164
|
+
this.#containerMain.appendChild(this.#slider);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Initializes and renders the menu UI, including buttons and slider.
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
#createMenu() {
|
|
172
|
+
this.#containerMain = document.createElement("div");
|
|
173
|
+
this.#containerMain.classList.add("pref-viewer-3d");
|
|
174
|
+
this.#containerMain.classList.add("animation-menu");
|
|
175
|
+
this.#containerMain.setAttribute("data-animation-name", this.#name);
|
|
176
|
+
this.#canvas.parentElement.prepend(this.#containerMain);
|
|
177
|
+
|
|
178
|
+
const style = document.createElement("style");
|
|
179
|
+
style.textContent = PrefViewer3DAnimationMenuStyles;
|
|
180
|
+
this.#containerMain.appendChild(style);
|
|
181
|
+
|
|
182
|
+
this.#containerButtons = document.createElement("div");
|
|
183
|
+
this.#containerButtons.classList.add("animation-menu-buttons");
|
|
184
|
+
this.#containerMain.appendChild(this.#containerButtons);
|
|
185
|
+
|
|
186
|
+
this.#createButtons();
|
|
187
|
+
this.#createSlider();
|
|
172
188
|
}
|
|
173
189
|
|
|
174
190
|
/**
|
|
@@ -178,24 +194,37 @@ export class OpeningAnimationMenu {
|
|
|
178
194
|
* @returns {Button|null} The button control or null if not found.
|
|
179
195
|
*/
|
|
180
196
|
#getButtonByName(name) {
|
|
181
|
-
return this.#
|
|
197
|
+
return this.#containerButtons.querySelector(`button[name="button_animation_${name}"]`);
|
|
182
198
|
}
|
|
183
199
|
|
|
184
200
|
/**
|
|
185
|
-
*
|
|
201
|
+
* Combines player and loop button states.
|
|
186
202
|
* @private
|
|
187
|
-
* @
|
|
188
|
-
* @param {boolean} enabled
|
|
189
|
-
* @param {boolean} active
|
|
190
|
-
* @param {boolean} visible
|
|
203
|
+
* @returns {object}
|
|
191
204
|
*/
|
|
192
|
-
#
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
205
|
+
#getButtonsState() {
|
|
206
|
+
return Object.assign(this.#getPlayerButtonsState(), this.#getLoopButtonsState());
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Returns the state for loop control buttons.
|
|
211
|
+
* @private
|
|
212
|
+
* @returns {object}
|
|
213
|
+
*/
|
|
214
|
+
#getLoopButtonsState() {
|
|
215
|
+
const buttonsState = {
|
|
216
|
+
repeat: {
|
|
217
|
+
enabled: this.#animationLoop,
|
|
218
|
+
active: false,
|
|
219
|
+
visible: this.#animationLoop,
|
|
220
|
+
},
|
|
221
|
+
repeatOff: {
|
|
222
|
+
enabled: !this.#animationLoop,
|
|
223
|
+
active: false,
|
|
224
|
+
visible: !this.#animationLoop,
|
|
225
|
+
},
|
|
226
|
+
};
|
|
227
|
+
return buttonsState;
|
|
199
228
|
}
|
|
200
229
|
|
|
201
230
|
/**
|
|
@@ -235,33 +264,33 @@ export class OpeningAnimationMenu {
|
|
|
235
264
|
}
|
|
236
265
|
|
|
237
266
|
/**
|
|
238
|
-
*
|
|
267
|
+
* Updates the visual state of a button (enabled, active, visible).
|
|
239
268
|
* @private
|
|
240
|
-
* @
|
|
269
|
+
* @param {string} name - Button identifier.
|
|
270
|
+
* @param {boolean} enabled
|
|
271
|
+
* @param {boolean} active
|
|
272
|
+
* @param {boolean} visible
|
|
241
273
|
*/
|
|
242
|
-
#
|
|
243
|
-
const
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
visible: !this.#animationLoop,
|
|
253
|
-
},
|
|
254
|
-
};
|
|
255
|
-
return buttonsState;
|
|
274
|
+
#setButtonState(name, enabled, active, visible = true) {
|
|
275
|
+
const button = this.#getButtonByName(name);
|
|
276
|
+
if (!button) {
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
const classToRemove = ["active", "enabled", "disabled", "hidden", "visible"];
|
|
280
|
+
button.classList.remove(...classToRemove);
|
|
281
|
+
const stateClass = active ? "active" : enabled ? "enabled" : "disabled";
|
|
282
|
+
const visibilityClass = visible ? "visible" : "hidden";
|
|
283
|
+
button.classList.add(stateClass, visibilityClass);
|
|
256
284
|
}
|
|
257
285
|
|
|
258
286
|
/**
|
|
259
|
-
*
|
|
287
|
+
* Updates all loop control buttons according to current loop mode.
|
|
260
288
|
* @private
|
|
261
|
-
* @returns {object}
|
|
262
289
|
*/
|
|
263
|
-
#
|
|
264
|
-
|
|
290
|
+
#setLoopButtonsState() {
|
|
291
|
+
const buttonsState = this.#getLoopButtonsState();
|
|
292
|
+
this.#setButtonState("repeat", buttonsState.repeat.enabled, buttonsState.repeat.active, buttonsState.repeat.visible);
|
|
293
|
+
this.#setButtonState("repeatOff", buttonsState.repeatOff.enabled, buttonsState.repeatOff.active, buttonsState.repeatOff.visible);
|
|
265
294
|
}
|
|
266
295
|
|
|
267
296
|
/**
|
|
@@ -278,46 +307,38 @@ export class OpeningAnimationMenu {
|
|
|
278
307
|
}
|
|
279
308
|
|
|
280
309
|
/**
|
|
281
|
-
*
|
|
310
|
+
* Handles the slider input event for animation progress.
|
|
282
311
|
* @private
|
|
312
|
+
* @param {Event} event - The input event from the slider.
|
|
313
|
+
* @returns {void}
|
|
314
|
+
* @description
|
|
315
|
+
* If the slider value is being set programmatically, the event is ignored to prevent callback loops.
|
|
283
316
|
*/
|
|
284
|
-
#
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
317
|
+
#onSliderInput(event) {
|
|
318
|
+
if (this.#callbacks && typeof this.#callbacks.onSetAnimationProgress === "function") {
|
|
319
|
+
this.#callbacks.onSetAnimationProgress(event.target.value);
|
|
320
|
+
}
|
|
288
321
|
}
|
|
289
322
|
|
|
290
323
|
/**
|
|
291
|
-
*
|
|
292
|
-
*
|
|
324
|
+
* ---------------------------
|
|
325
|
+
* Public methods
|
|
326
|
+
* ---------------------------
|
|
293
327
|
*/
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
};
|
|
309
|
-
this.#slider = new Slider("slider_animation_progress");
|
|
310
|
-
Object.assign(this.#slider, sliderProps);
|
|
311
|
-
this.#slider.onValueChangedObservable.add((value) => {
|
|
312
|
-
if (this.#isSettingSliderValue) {
|
|
313
|
-
this.#isSettingSliderValue = false;
|
|
314
|
-
return;
|
|
315
|
-
}
|
|
316
|
-
if (this.#callbacks && typeof this.#callbacks.onSetAnimationProgress === "function") {
|
|
317
|
-
this.#callbacks.onSetAnimationProgress(value);
|
|
318
|
-
}
|
|
319
|
-
});
|
|
320
|
-
this.#mainPanel.addControl(this.#slider);
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Disposes the animation menu and releases all associated DOM resources.
|
|
331
|
+
* @public
|
|
332
|
+
* @returns {void}
|
|
333
|
+
*/
|
|
334
|
+
dispose() {
|
|
335
|
+
this.#slider.removeEventListener("input", this.#handler.onSliderInput);
|
|
336
|
+
if (this.isVisible) {
|
|
337
|
+
this.#containerMain.remove();
|
|
338
|
+
}
|
|
339
|
+
this.#containerMain = null;
|
|
340
|
+
this.#containerButtons = null;
|
|
341
|
+
this.#slider = null;
|
|
321
342
|
}
|
|
322
343
|
|
|
323
344
|
/**
|
|
@@ -338,14 +359,12 @@ export class OpeningAnimationMenu {
|
|
|
338
359
|
|
|
339
360
|
/**
|
|
340
361
|
* Sets the animation progress value and updates the slider position.
|
|
341
|
-
* When called, the slider value is updated programmatically without triggering the slider's value change callback.
|
|
342
362
|
* @public
|
|
343
363
|
* @param {number} progress - The new animation progress value (between 0 and 1).
|
|
344
364
|
*/
|
|
345
365
|
set animationProgress(progress) {
|
|
346
366
|
this.#animationProgress = progress;
|
|
347
|
-
this.#
|
|
348
|
-
this.#slider.value = progress;
|
|
367
|
+
this.#slider.value = progress.toString();
|
|
349
368
|
}
|
|
350
369
|
|
|
351
370
|
/**
|
|
@@ -357,4 +376,20 @@ export class OpeningAnimationMenu {
|
|
|
357
376
|
this.#animationState = state;
|
|
358
377
|
this.#setPlayerButtonsState();
|
|
359
378
|
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* ---------------------------
|
|
382
|
+
* Public getters
|
|
383
|
+
* ---------------------------
|
|
384
|
+
*/
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* Returns whether the animation menu is currently visible in the DOM.
|
|
388
|
+
* @public
|
|
389
|
+
* @returns {boolean} True if the menu is visible, false otherwise.
|
|
390
|
+
*/
|
|
391
|
+
get isVisible() {
|
|
392
|
+
const menuElement = this.#canvas.parentElement.querySelector(`div.animation-menu[data-animation-name="${this.#name}"]`);
|
|
393
|
+
return !!menuElement;
|
|
394
|
+
}
|
|
360
395
|
}
|