@preference-sl/pref-viewer 2.11.0-beta.3 → 2.11.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -2
- package/src/babylonjs-animation-controller.js +51 -392
- package/src/babylonjs-animation-opening-menu.js +360 -0
- package/src/babylonjs-animation-opening.js +496 -0
- package/src/babylonjs-controller.js +55 -34
- package/src/pref-viewer-3d.js +1 -1
- package/src/images/icon-pause.svg +0 -1
- package/src/images/icon-play-backwards.svg +0 -1
- package/src/images/icon-play.svg +0 -1
- package/src/images/icon-skip-backward.svg +0 -1
- package/src/images/icon-skip-forward.svg +0 -1
|
@@ -0,0 +1,360 @@
|
|
|
1
|
+
import { AdvancedDynamicTexture, Button, Control, Image, Slider, StackPanel } from "@babylonjs/gui";
|
|
2
|
+
import { OpeningAnimation } from "./babylonjs-animation-opening.js";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* OpeningAnimationMenu - Manages and renders the animation control menu for opening/closing animations in a Babylon.js scene.
|
|
6
|
+
*
|
|
7
|
+
* Responsibilities:
|
|
8
|
+
* - Renders a GUI menu with buttons for controlling animation playback (open, close, pause, go to opened/closed, loop).
|
|
9
|
+
* - Updates button states and slider position based on animation state, progress, and loop mode.
|
|
10
|
+
* - Handles user interactions and invokes provided callbacks for animation actions.
|
|
11
|
+
* - Synchronizes the slider value with animation progress, avoiding callback loops.
|
|
12
|
+
*
|
|
13
|
+
* Public Setters:
|
|
14
|
+
* - set animationState(state): Updates the animation state and button states.
|
|
15
|
+
* - set animationProgress(progress): Updates the animation progress and slider value.
|
|
16
|
+
* - set animationLoop(loop): Updates the loop mode and loop button states.
|
|
17
|
+
*
|
|
18
|
+
* Private Methods:
|
|
19
|
+
* - #createMenu(): Initializes and renders the menu UI.
|
|
20
|
+
* - #addButton(name, imageURL, enabled, active, visible, callback): Adds a button to the menu with specified properties.
|
|
21
|
+
* - #createButtons(): Creates all control buttons and sets their initial states.
|
|
22
|
+
* - #getButtonByName(name): Retrieves a button control by its name.
|
|
23
|
+
* - #setButtonState(name, enabled, active, visible): Updates the visual state of a button.
|
|
24
|
+
* - #getPlayerButtonsState(): Returns the state (enabled, active, visible) for playback control buttons.
|
|
25
|
+
* - #getLoopButtonsState(): Returns the state for loop control buttons.
|
|
26
|
+
* - #getButtonsState(): Combines player and loop button states.
|
|
27
|
+
* - #setPlayerButtonsState(): Updates all playback control buttons.
|
|
28
|
+
* - #setLoopButtonsState(): Updates all loop control buttons.
|
|
29
|
+
* - #createSlider(): Creates and configures the animation progress slider.
|
|
30
|
+
*
|
|
31
|
+
* Usage Example:
|
|
32
|
+
* const menu = new OpeningAnimationMenu(adt, state, progress, loop, {
|
|
33
|
+
* onOpen: () => { ... },
|
|
34
|
+
* onClose: () => { ... },
|
|
35
|
+
* onPause: () => { ... },
|
|
36
|
+
* onGoToOpened: () => { ... },
|
|
37
|
+
* onGoToClosed: () => { ... },
|
|
38
|
+
* onToggleLoop: () => { ... },
|
|
39
|
+
* onSetAnimationProgress: (progress) => { ... }
|
|
40
|
+
* });
|
|
41
|
+
* menu.animationState = OpeningAnimation.states.opening;
|
|
42
|
+
* menu.animationProgress = 0.5;
|
|
43
|
+
* menu.animationLoop = true;
|
|
44
|
+
*/
|
|
45
|
+
export class OpeningAnimationMenu {
|
|
46
|
+
#animationState = OpeningAnimation.states.closed;
|
|
47
|
+
#animationProgress = 0;
|
|
48
|
+
#animationLoop = false;
|
|
49
|
+
#callbacks = null;
|
|
50
|
+
|
|
51
|
+
// GUI Elements
|
|
52
|
+
#advancedDynamicTexture = null;
|
|
53
|
+
#mainPanel = null;
|
|
54
|
+
#secondaryPanel = null;
|
|
55
|
+
#slider = null;
|
|
56
|
+
|
|
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
|
+
#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 fill="${this.#colorIcon}" d="M16,18.86V4.86l-11,7,11,7Z"/></svg>`,
|
|
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 fill="${this.#colorIcon}" d="M20,5V19L13,12M6,5V19H4V5M13,5V19L6,12"/></svg>`,
|
|
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 fill="${this.#colorIcon}" d="M8,5.14v14l11-7-11-7Z"/></svg>`,
|
|
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 fill="${this.#colorIcon}" d="M4,5V19L11,12M18,5V19H20V5M11,5V19L18,12"/></svg>`,
|
|
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 fill="${this.#colorIcon}" d="M14,19H18V5H14M6,19H10V5H6V19Z"/></svg>`,
|
|
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 fill="${this.#colorIcon}" d="M17,17H7V14L3,18L7,22V19H19V13H17M7,7H17V10L21,6L17,2V5H5V11H7V7Z"/></svg>`,
|
|
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 fill="${this.#colorIcon}" 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
|
+
};
|
|
76
|
+
|
|
77
|
+
#isSettingSliderValue = false;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Constructs the OpeningAnimationMenu and initializes the menu UI.
|
|
81
|
+
* @param {AdvancedDynamicTexture} advancedDynamicTexture - Babylon.js GUI texture for rendering controls.
|
|
82
|
+
* @param {number} animationState - Current animation state (enum).
|
|
83
|
+
* @param {number} animationProgress - Current animation progress (0 to 1).
|
|
84
|
+
* @param {boolean} animationLoop - Whether the animation is set to loop.
|
|
85
|
+
* @param {object} callbacks - Callback functions for menu actions (play, pause, open, close, etc.).
|
|
86
|
+
* @public
|
|
87
|
+
*/
|
|
88
|
+
constructor(advancedDynamicTexture, animationState, animationProgress, animationLoop, callbacks) {
|
|
89
|
+
this.#advancedDynamicTexture = advancedDynamicTexture;
|
|
90
|
+
this.#animationState = animationState;
|
|
91
|
+
this.#animationProgress = animationProgress;
|
|
92
|
+
this.#animationLoop = animationLoop;
|
|
93
|
+
this.#callbacks = callbacks;
|
|
94
|
+
|
|
95
|
+
this.#createMenu(animationState);
|
|
96
|
+
}
|
|
97
|
+
|
|
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
|
+
/**
|
|
122
|
+
* Internal helper to add a button to the menu.
|
|
123
|
+
* Sets button appearance and attaches the callback for user interaction.
|
|
124
|
+
* @private
|
|
125
|
+
* @param {string} name - Button identifier.
|
|
126
|
+
* @param {string} imageURL - SVG image data URL for the button icon.
|
|
127
|
+
* @param {boolean} enabled - Whether the button is enabled.
|
|
128
|
+
* @param {boolean} active - Whether the button is visually active.
|
|
129
|
+
* @param {boolean} visible - Whether the button is visible.
|
|
130
|
+
* @param {function} callback - Callback to invoke on button click.
|
|
131
|
+
*/
|
|
132
|
+
#addButton(name, imageURL, enabled = true, active = false, visible = true, callback) {
|
|
133
|
+
const buttonProps = {
|
|
134
|
+
background: active ? this.#colorActive : enabled ? this.#colorEnabled : this.#colorDisabled,
|
|
135
|
+
color: this.#colorBorder,
|
|
136
|
+
cornerRadius: 0,
|
|
137
|
+
height: `${this.#buttonSize}px`,
|
|
138
|
+
hoverCursor: "pointer",
|
|
139
|
+
width: `${this.#buttonSize}px`,
|
|
140
|
+
isVisible: visible,
|
|
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(() => {
|
|
146
|
+
if (callback && typeof callback === "function") {
|
|
147
|
+
callback();
|
|
148
|
+
}
|
|
149
|
+
});
|
|
150
|
+
this.#secondaryPanel.addControl(button);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Creates all control buttons and sets their initial states.
|
|
155
|
+
* @private
|
|
156
|
+
*/
|
|
157
|
+
#createButtons() {
|
|
158
|
+
const buttonsState = this.#getButtonsState();
|
|
159
|
+
this.#addButton("closed", `data:image/svg+xml,${encodeURIComponent(this.#icon.closed)}`, buttonsState.closed.enabled, buttonsState.closed.active, buttonsState.closed.visible, this.#callbacks.onGoToClosed);
|
|
160
|
+
this.#addButton("close", `data:image/svg+xml,${encodeURIComponent(this.#icon.close)}`, buttonsState.close.enabled, buttonsState.close.active, buttonsState.close.visible, this.#callbacks.onClose);
|
|
161
|
+
this.#addButton("pause", `data:image/svg+xml,${encodeURIComponent(this.#icon.pause)}`, buttonsState.pause.enabled, buttonsState.pause.active, buttonsState.pause.visible, this.#callbacks.onPause);
|
|
162
|
+
this.#addButton("open", `data:image/svg+xml,${encodeURIComponent(this.#icon.open)}`, buttonsState.open.enabled, buttonsState.open.active, buttonsState.open.visible, this.#callbacks.onOpen);
|
|
163
|
+
this.#addButton("opened", `data:image/svg+xml,${encodeURIComponent(this.#icon.opened)}`, buttonsState.opened.enabled, buttonsState.opened.active, buttonsState.opened.visible, this.#callbacks.onGoToOpened);
|
|
164
|
+
this.#addButton("repeat", `data:image/svg+xml,${encodeURIComponent(this.#icon.repeat)}`, buttonsState.repeat.enabled, buttonsState.repeat.active, buttonsState.repeat.visible, this.#callbacks.onToggleLoop);
|
|
165
|
+
this.#addButton("repeatOff", `data:image/svg+xml,${encodeURIComponent(this.#icon.repeatOff)}`, buttonsState.repeatOff.enabled, buttonsState.repeatOff.active, buttonsState.repeatOff.visible, this.#callbacks.onToggleLoop);
|
|
166
|
+
|
|
167
|
+
// Adjust padding for loop buttons
|
|
168
|
+
this.#getButtonByName("repeat").paddingLeft = `${this.#buttonLoopPaddingLeft}px`;
|
|
169
|
+
this.#getButtonByName("repeat").width = `${this.#buttonSize + this.#buttonLoopPaddingLeft}px`;
|
|
170
|
+
this.#getButtonByName("repeatOff").paddingLeft = `${this.#buttonLoopPaddingLeft}px`;
|
|
171
|
+
this.#getButtonByName("repeatOff").width = `${this.#buttonSize + this.#buttonLoopPaddingLeft}px`;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Retrieves a button control by its name.
|
|
176
|
+
* @private
|
|
177
|
+
* @param {string} name - Button identifier.
|
|
178
|
+
* @returns {Button|null} The button control or null if not found.
|
|
179
|
+
*/
|
|
180
|
+
#getButtonByName(name) {
|
|
181
|
+
return this.#advancedDynamicTexture.getControlByName(`button_animation_${name}`);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Updates the visual state of a button (enabled, active, visible).
|
|
186
|
+
* @private
|
|
187
|
+
* @param {string} name - Button identifier.
|
|
188
|
+
* @param {boolean} enabled
|
|
189
|
+
* @param {boolean} active
|
|
190
|
+
* @param {boolean} visible
|
|
191
|
+
*/
|
|
192
|
+
#setButtonState(name, enabled, active, visible = true) {
|
|
193
|
+
const button = this.#getButtonByName(name);
|
|
194
|
+
if (!button) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
button.background = active ? this.#colorActive : enabled ? this.#colorEnabled : this.#colorDisabled;
|
|
198
|
+
button.isVisible = visible;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Returns the state (enabled, active, visible) for playback control buttons.
|
|
203
|
+
* @private
|
|
204
|
+
* @returns {object}
|
|
205
|
+
*/
|
|
206
|
+
#getPlayerButtonsState() {
|
|
207
|
+
const buttonsState = {
|
|
208
|
+
opened: {
|
|
209
|
+
enabled: this.#animationState !== OpeningAnimation.states.opened,
|
|
210
|
+
active: false,
|
|
211
|
+
visible: true,
|
|
212
|
+
},
|
|
213
|
+
open: {
|
|
214
|
+
enabled: this.#animationState !== OpeningAnimation.states.opened && this.#animationState !== OpeningAnimation.states.opening,
|
|
215
|
+
active: this.#animationState === OpeningAnimation.states.opening,
|
|
216
|
+
visible: true,
|
|
217
|
+
},
|
|
218
|
+
pause: {
|
|
219
|
+
enabled: this.#animationState !== OpeningAnimation.states.paused && this.#animationState !== OpeningAnimation.states.closed && this.#animationState !== OpeningAnimation.states.opened,
|
|
220
|
+
active: this.#animationState === OpeningAnimation.states.paused,
|
|
221
|
+
visible: true,
|
|
222
|
+
},
|
|
223
|
+
close: {
|
|
224
|
+
enabled: this.#animationState !== OpeningAnimation.states.closed && this.#animationState !== OpeningAnimation.states.closing,
|
|
225
|
+
active: this.#animationState === OpeningAnimation.states.closing,
|
|
226
|
+
visible: true,
|
|
227
|
+
},
|
|
228
|
+
closed: {
|
|
229
|
+
enabled: this.#animationState !== OpeningAnimation.states.closed,
|
|
230
|
+
active: false,
|
|
231
|
+
visible: true,
|
|
232
|
+
},
|
|
233
|
+
};
|
|
234
|
+
return buttonsState;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Returns the state for loop control buttons.
|
|
239
|
+
* @private
|
|
240
|
+
* @returns {object}
|
|
241
|
+
*/
|
|
242
|
+
#getLoopButtonsState() {
|
|
243
|
+
const buttonsState = {
|
|
244
|
+
repeat: {
|
|
245
|
+
enabled: this.#animationLoop,
|
|
246
|
+
active: false,
|
|
247
|
+
visible: this.#animationLoop,
|
|
248
|
+
},
|
|
249
|
+
repeatOff: {
|
|
250
|
+
enabled: !this.#animationLoop,
|
|
251
|
+
active: false,
|
|
252
|
+
visible: !this.#animationLoop,
|
|
253
|
+
},
|
|
254
|
+
};
|
|
255
|
+
return buttonsState;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Combines player and loop button states.
|
|
260
|
+
* @private
|
|
261
|
+
* @returns {object}
|
|
262
|
+
*/
|
|
263
|
+
#getButtonsState() {
|
|
264
|
+
return Object.assign(this.#getPlayerButtonsState(), this.#getLoopButtonsState());
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Updates all playback control buttons according to current animation state.
|
|
269
|
+
* @private
|
|
270
|
+
*/
|
|
271
|
+
#setPlayerButtonsState() {
|
|
272
|
+
const buttonsState = this.#getPlayerButtonsState();
|
|
273
|
+
this.#setButtonState("opened", buttonsState.opened.enabled, buttonsState.opened.active, buttonsState.opened.visible);
|
|
274
|
+
this.#setButtonState("open", buttonsState.open.enabled, buttonsState.open.active, buttonsState.open.visible);
|
|
275
|
+
this.#setButtonState("pause", buttonsState.pause.enabled, buttonsState.pause.active, buttonsState.pause.visible);
|
|
276
|
+
this.#setButtonState("close", buttonsState.close.enabled, buttonsState.close.active, buttonsState.close.visible);
|
|
277
|
+
this.#setButtonState("closed", buttonsState.closed.enabled, buttonsState.closed.active, buttonsState.closed.visible);
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Updates all loop control buttons according to current loop mode.
|
|
282
|
+
* @private
|
|
283
|
+
*/
|
|
284
|
+
#setLoopButtonsState() {
|
|
285
|
+
const buttonsState = this.#getLoopButtonsState();
|
|
286
|
+
this.#setButtonState("repeat", buttonsState.repeat.enabled, buttonsState.repeat.active, buttonsState.repeat.visible);
|
|
287
|
+
this.#setButtonState("repeatOff", buttonsState.repeatOff.enabled, buttonsState.repeatOff.active, buttonsState.repeatOff.visible);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Creates and configures the animation progress slider.
|
|
292
|
+
* @private
|
|
293
|
+
*/
|
|
294
|
+
#createSlider() {
|
|
295
|
+
const sliderProps = {
|
|
296
|
+
minimum: 0,
|
|
297
|
+
maximum: 1,
|
|
298
|
+
value: this.#animationProgress,
|
|
299
|
+
height: `${this.#buttonSize}px`,
|
|
300
|
+
width: `${this.#buttonSize * 7 + this.#buttonLoopPaddingLeft}px`, // Width based on number of buttons visible
|
|
301
|
+
barOffset: `${this.#sliderBarOffset}px`,
|
|
302
|
+
isThumbCircle: true,
|
|
303
|
+
thumbWidth: `${this.#sliderThumbWidth}px`,
|
|
304
|
+
background: this.#colorDisabled,
|
|
305
|
+
color: this.#colorEnabled,
|
|
306
|
+
borderColor: this.#colorBorder,
|
|
307
|
+
thumbColor: this.#colorEnabled,
|
|
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);
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* ---------------------------
|
|
325
|
+
* Public setters
|
|
326
|
+
* ---------------------------
|
|
327
|
+
*/
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Sets the animation loop mode and updates loop button states.
|
|
331
|
+
* @public
|
|
332
|
+
* @param {boolean} loop
|
|
333
|
+
*/
|
|
334
|
+
set animationLoop(loop) {
|
|
335
|
+
this.#animationLoop = loop;
|
|
336
|
+
this.#setLoopButtonsState();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* 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
|
+
* @public
|
|
343
|
+
* @param {number} progress - The new animation progress value (between 0 and 1).
|
|
344
|
+
*/
|
|
345
|
+
set animationProgress(progress) {
|
|
346
|
+
this.#animationProgress = progress;
|
|
347
|
+
this.#isSettingSliderValue = true;
|
|
348
|
+
this.#slider.value = progress;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Sets the animation state and updates playback button states.
|
|
353
|
+
* @public
|
|
354
|
+
* @param {number} state - The new animation state (enum).
|
|
355
|
+
*/
|
|
356
|
+
set animationState(state) {
|
|
357
|
+
this.#animationState = state;
|
|
358
|
+
this.#setPlayerButtonsState();
|
|
359
|
+
}
|
|
360
|
+
}
|