@tsparticles/plugin-sounds 3.0.2 → 3.1.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/browser/Options/Classes/Sounds.js +4 -0
- package/browser/Options/Classes/SoundsEvent.js +4 -3
- package/browser/Options/Classes/SoundsIcon.js +1 -0
- package/browser/Options/Classes/SoundsIcons.js +4 -0
- package/browser/SoundsInstance.js +130 -69
- package/browser/index.js +13 -0
- package/browser/utils.js +11 -4
- package/cjs/Options/Classes/Sounds.js +4 -0
- package/cjs/Options/Classes/SoundsEvent.js +4 -3
- package/cjs/Options/Classes/SoundsIcon.js +1 -0
- package/cjs/Options/Classes/SoundsIcons.js +4 -0
- package/cjs/SoundsInstance.js +128 -67
- package/cjs/index.js +13 -0
- package/cjs/utils.js +14 -5
- package/esm/Options/Classes/Sounds.js +4 -0
- package/esm/Options/Classes/SoundsEvent.js +4 -3
- package/esm/Options/Classes/SoundsIcon.js +1 -0
- package/esm/Options/Classes/SoundsIcons.js +4 -0
- package/esm/SoundsInstance.js +130 -69
- package/esm/index.js +13 -0
- package/esm/utils.js +11 -4
- package/package.json +2 -2
- package/report.html +2 -2
- package/tsparticles.plugin.sounds.js +180 -77
- package/tsparticles.plugin.sounds.min.js +1 -1
- package/tsparticles.plugin.sounds.min.js.LICENSE.txt +1 -1
- package/types/Options/Classes/Sounds.d.ts +1 -0
- package/types/Options/Classes/SoundsEvent.d.ts +0 -5
- package/types/Options/Classes/SoundsIcon.d.ts +1 -0
- package/types/Options/Classes/SoundsIcons.d.ts +1 -0
- package/types/Options/Interfaces/ISounds.d.ts +1 -0
- package/types/Options/Interfaces/ISoundsIcon.d.ts +1 -0
- package/types/Options/Interfaces/ISoundsIcons.d.ts +1 -0
- package/types/SoundsInstance.d.ts +6 -0
- package/types/index.d.ts +1 -1
- package/types/types.d.ts +5 -5
- package/types/utils.d.ts +2 -0
- package/umd/Options/Classes/Sounds.js +4 -0
- package/umd/Options/Classes/SoundsEvent.js +4 -3
- package/umd/Options/Classes/SoundsIcon.js +1 -0
- package/umd/Options/Classes/SoundsIcons.js +4 -0
- package/umd/SoundsInstance.js +128 -67
- package/umd/index.js +14 -1
- package/umd/utils.js +14 -5
|
@@ -13,10 +13,16 @@ export declare class SoundsInstance implements IContainerPlugin {
|
|
|
13
13
|
private _volumeUpImg?;
|
|
14
14
|
constructor(container: SoundsContainer, engine: Engine);
|
|
15
15
|
init(): Promise<void>;
|
|
16
|
+
mute(): Promise<void>;
|
|
16
17
|
start(): Promise<void>;
|
|
17
18
|
stop(): void;
|
|
19
|
+
toggleMute(): Promise<void>;
|
|
20
|
+
unmute(): Promise<void>;
|
|
21
|
+
volumeDown(): Promise<void>;
|
|
22
|
+
volumeUp(): Promise<void>;
|
|
18
23
|
private readonly _addBuffer;
|
|
19
24
|
private readonly _addOscillator;
|
|
25
|
+
private _getAudioContext;
|
|
20
26
|
private readonly _initEvents;
|
|
21
27
|
private readonly _mute;
|
|
22
28
|
private readonly _playBuffer;
|
package/types/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type Engine } from "@tsparticles/engine";
|
|
2
2
|
export declare function loadSoundsPlugin(engine: Engine, refresh?: boolean): Promise<void>;
|
package/types/types.d.ts
CHANGED
|
@@ -15,12 +15,12 @@ export type SoundsContainer = Container & {
|
|
|
15
15
|
audioContext?: AudioContext;
|
|
16
16
|
muted?: boolean;
|
|
17
17
|
};
|
|
18
|
-
export
|
|
18
|
+
export interface ImageMargins {
|
|
19
19
|
right: number;
|
|
20
20
|
top: number;
|
|
21
|
-
}
|
|
22
|
-
export
|
|
23
|
-
clickCb: () => void
|
|
21
|
+
}
|
|
22
|
+
export interface InitImageData {
|
|
23
|
+
clickCb: () => Promise<void>;
|
|
24
24
|
container: SoundsContainer;
|
|
25
25
|
display: ImageDisplay;
|
|
26
26
|
iconOptions: SoundsIcon;
|
|
@@ -28,4 +28,4 @@ export type InitImageData = {
|
|
|
28
28
|
options: Options;
|
|
29
29
|
pos: ImageMargins;
|
|
30
30
|
rightOffsets: number[];
|
|
31
|
-
}
|
|
31
|
+
}
|
package/types/utils.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
const SoundsVolume_js_1 = require("./SoundsVolume.js");
|
|
16
16
|
class Sounds {
|
|
17
17
|
constructor() {
|
|
18
|
+
this.autoPlay = true;
|
|
18
19
|
this.enable = false;
|
|
19
20
|
this.events = [];
|
|
20
21
|
this.icons = new SoundsIcons_js_1.SoundsIcons();
|
|
@@ -24,6 +25,9 @@
|
|
|
24
25
|
if (!data) {
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
28
|
+
if (data.autoPlay !== undefined) {
|
|
29
|
+
this.autoPlay = data.autoPlay;
|
|
30
|
+
}
|
|
27
31
|
if (data.enable !== undefined) {
|
|
28
32
|
this.enable = data.enable;
|
|
29
33
|
}
|
|
@@ -53,10 +53,11 @@
|
|
|
53
53
|
return tmp;
|
|
54
54
|
});
|
|
55
55
|
}
|
|
56
|
-
if (data.filter
|
|
56
|
+
if (data.filter) {
|
|
57
57
|
if ((0, engine_1.isString)(data.filter)) {
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
const filterFunc = window[data.filter];
|
|
59
|
+
if ((0, engine_1.isFunction)(filterFunc)) {
|
|
60
|
+
this.filter = filterFunc;
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
else {
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
this.unmute = new SoundsIcon_js_1.SoundsIcon();
|
|
18
18
|
this.volumeDown = new SoundsIcon_js_1.SoundsIcon();
|
|
19
19
|
this.volumeUp = new SoundsIcon_js_1.SoundsIcon();
|
|
20
|
+
this.enable = false;
|
|
20
21
|
this.mute.svg = `<?xml version="1.0"?>
|
|
21
22
|
<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
|
|
22
23
|
xml:space="preserve" xmlns="http://www.w3.org/2000/svg"
|
|
@@ -58,6 +59,9 @@
|
|
|
58
59
|
if (!data) {
|
|
59
60
|
return;
|
|
60
61
|
}
|
|
62
|
+
if (data.enable !== undefined) {
|
|
63
|
+
this.enable = data.enable;
|
|
64
|
+
}
|
|
61
65
|
this.mute.load(data.mute);
|
|
62
66
|
this.unmute.load(data.unmute);
|
|
63
67
|
this.volumeDown.load(data.volumeDown);
|
package/umd/SoundsInstance.js
CHANGED
|
@@ -12,13 +12,19 @@
|
|
|
12
12
|
exports.SoundsInstance = void 0;
|
|
13
13
|
const engine_1 = require("@tsparticles/engine");
|
|
14
14
|
const utils_js_1 = require("./utils.js");
|
|
15
|
+
const zIndexOffset = 1, rightOffset = 1, minVolume = 0;
|
|
15
16
|
function initImage(data) {
|
|
16
|
-
const img = document.createElement("img"), { clickCb, container, display, iconOptions, margin, options, pos, rightOffsets } = data, { width, path, svg } = iconOptions;
|
|
17
|
-
setIconStyle(img, pos.top + margin, pos.right -
|
|
17
|
+
const img = document.createElement("img"), { clickCb, container, display, iconOptions, margin, options, pos, rightOffsets } = data, { width, path, style, svg } = iconOptions, defaultAccumulator = 0;
|
|
18
|
+
setIconStyle(img, pos.top + margin, pos.right -
|
|
19
|
+
(margin * (rightOffsets.length + rightOffset) +
|
|
20
|
+
width +
|
|
21
|
+
rightOffsets.reduce((a, b) => a + b, defaultAccumulator)), display, options.fullScreen.zIndex + zIndexOffset, width, margin, style);
|
|
18
22
|
img.src = path ?? (svg ? `data:image/svg+xml;base64,${btoa(svg)}` : "");
|
|
19
|
-
const parent = container.canvas.element?.parentNode
|
|
23
|
+
const parent = container.canvas.element?.parentNode ?? document.body;
|
|
20
24
|
parent.append(img);
|
|
21
|
-
img.addEventListener("click",
|
|
25
|
+
img.addEventListener("click", () => {
|
|
26
|
+
void clickCb();
|
|
27
|
+
});
|
|
22
28
|
return img;
|
|
23
29
|
}
|
|
24
30
|
function removeImage(image) {
|
|
@@ -27,14 +33,15 @@
|
|
|
27
33
|
}
|
|
28
34
|
image.remove();
|
|
29
35
|
}
|
|
30
|
-
function setIconStyle(icon, top, left, display, zIndex, width, margin) {
|
|
36
|
+
function setIconStyle(icon, top, left, display, zIndex, width, margin, style) {
|
|
31
37
|
icon.style.userSelect = "none";
|
|
32
38
|
icon.style.webkitUserSelect = "none";
|
|
33
39
|
icon.style.position = "absolute";
|
|
34
40
|
icon.style.top = `${top + margin}px`;
|
|
35
41
|
icon.style.left = `${left - margin - width}px`;
|
|
36
42
|
icon.style.display = display;
|
|
37
|
-
icon.style.zIndex = `${zIndex +
|
|
43
|
+
icon.style.zIndex = `${zIndex + zIndexOffset}`;
|
|
44
|
+
icon.style.cssText += style;
|
|
38
45
|
}
|
|
39
46
|
class SoundsInstance {
|
|
40
47
|
constructor(container, engine) {
|
|
@@ -55,12 +62,12 @@
|
|
|
55
62
|
}
|
|
56
63
|
for (const event of soundsOptions.events) {
|
|
57
64
|
const cb = (args) => {
|
|
58
|
-
(async () => {
|
|
65
|
+
void (async () => {
|
|
59
66
|
const filterNotValid = event.filter && !event.filter(args);
|
|
60
67
|
if (this._container !== args.container) {
|
|
61
68
|
return;
|
|
62
69
|
}
|
|
63
|
-
if (!this._container || this._container.muted || this._container.destroyed) {
|
|
70
|
+
if (!this._container || !!this._container.muted || this._container.destroyed) {
|
|
64
71
|
(0, engine_1.executeOnSingleOrMultiple)(event.event, (item) => {
|
|
65
72
|
this._engine.removeEventListener(item, cb);
|
|
66
73
|
});
|
|
@@ -69,21 +76,22 @@
|
|
|
69
76
|
if (filterNotValid) {
|
|
70
77
|
return;
|
|
71
78
|
}
|
|
79
|
+
const defaultNoteIndex = 0;
|
|
72
80
|
if (event.audio) {
|
|
73
81
|
this._playBuffer((0, engine_1.itemFromSingleOrMultiple)(event.audio));
|
|
74
82
|
}
|
|
75
83
|
else if (event.melodies) {
|
|
76
84
|
const melody = (0, engine_1.itemFromArray)(event.melodies);
|
|
77
85
|
if (melody.melodies.length) {
|
|
78
|
-
await Promise.allSettled(melody.melodies.map((m) => this._playNote(m.notes,
|
|
86
|
+
await Promise.allSettled(melody.melodies.map((m) => this._playNote(m.notes, defaultNoteIndex, melody.loop)));
|
|
79
87
|
}
|
|
80
88
|
else {
|
|
81
|
-
await this._playNote(melody.notes,
|
|
89
|
+
await this._playNote(melody.notes, defaultNoteIndex, melody.loop);
|
|
82
90
|
}
|
|
83
91
|
}
|
|
84
92
|
else if (event.notes) {
|
|
85
93
|
const note = (0, engine_1.itemFromArray)(event.notes);
|
|
86
|
-
await this._playNote([note],
|
|
94
|
+
await this._playNote([note], defaultNoteIndex, false);
|
|
87
95
|
}
|
|
88
96
|
})();
|
|
89
97
|
};
|
|
@@ -92,18 +100,15 @@
|
|
|
92
100
|
});
|
|
93
101
|
}
|
|
94
102
|
};
|
|
95
|
-
this._mute = () => {
|
|
96
|
-
const container = this._container;
|
|
97
|
-
if (!container.audioContext) {
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
103
|
+
this._mute = async () => {
|
|
104
|
+
const container = this._container, audioContext = this._getAudioContext();
|
|
100
105
|
for (const source of this._audioSources) {
|
|
101
106
|
this._removeAudioSource(source);
|
|
102
107
|
}
|
|
103
108
|
if (this._gain) {
|
|
104
109
|
this._gain.disconnect();
|
|
105
110
|
}
|
|
106
|
-
|
|
111
|
+
await audioContext.close();
|
|
107
112
|
container.audioContext = undefined;
|
|
108
113
|
this._engine.dispatchEvent("soundsMuted", { container: this._container });
|
|
109
114
|
};
|
|
@@ -123,10 +128,10 @@
|
|
|
123
128
|
source.start();
|
|
124
129
|
};
|
|
125
130
|
this._playFrequency = async (frequency, duration) => {
|
|
126
|
-
if (!this.
|
|
131
|
+
if (!this._gain || this._container.muted) {
|
|
127
132
|
return;
|
|
128
133
|
}
|
|
129
|
-
const oscillator = this._addOscillator(
|
|
134
|
+
const audioContext = this._getAudioContext(), oscillator = this._addOscillator(audioContext);
|
|
130
135
|
oscillator.connect(this._gain);
|
|
131
136
|
oscillator.type = "sine";
|
|
132
137
|
oscillator.frequency.value = frequency;
|
|
@@ -139,14 +144,13 @@
|
|
|
139
144
|
});
|
|
140
145
|
};
|
|
141
146
|
this._playMuteSound = () => {
|
|
142
|
-
|
|
143
|
-
if (!container.audioContext) {
|
|
147
|
+
if (this._container.muted) {
|
|
144
148
|
return;
|
|
145
149
|
}
|
|
146
|
-
const gain =
|
|
147
|
-
gain.connect(
|
|
150
|
+
const audioContext = this._getAudioContext(), gain = audioContext.createGain();
|
|
151
|
+
gain.connect(audioContext.destination);
|
|
148
152
|
gain.gain.value = 0;
|
|
149
|
-
const oscillator =
|
|
153
|
+
const oscillator = audioContext.createOscillator();
|
|
150
154
|
oscillator.connect(gain);
|
|
151
155
|
oscillator.type = "sine";
|
|
152
156
|
oscillator.frequency.value = 1;
|
|
@@ -170,7 +174,8 @@
|
|
|
170
174
|
return this._playNoteValue(notes, noteIdx, idx);
|
|
171
175
|
});
|
|
172
176
|
await ((0, engine_1.isArray)(promises) ? Promise.allSettled(promises) : promises);
|
|
173
|
-
|
|
177
|
+
const indexOffset = 1;
|
|
178
|
+
let nextNoteIdx = noteIdx + indexOffset;
|
|
174
179
|
if (loop && nextNoteIdx >= notes.length) {
|
|
175
180
|
nextNoteIdx = nextNoteIdx % notes.length;
|
|
176
181
|
}
|
|
@@ -199,29 +204,31 @@
|
|
|
199
204
|
this._removeAudioSource = (source) => {
|
|
200
205
|
source.stop();
|
|
201
206
|
source.disconnect();
|
|
202
|
-
|
|
207
|
+
const deleteCount = 1;
|
|
208
|
+
this._audioSources.splice(this._audioSources.indexOf(source), deleteCount);
|
|
203
209
|
};
|
|
204
210
|
this._unmute = () => {
|
|
205
211
|
const container = this._container, options = container.actualOptions, soundsOptions = options.sounds;
|
|
206
212
|
if (!soundsOptions) {
|
|
207
213
|
return;
|
|
208
214
|
}
|
|
209
|
-
|
|
210
|
-
container.audioContext = new AudioContext();
|
|
211
|
-
}
|
|
212
|
-
const { audioContext } = container;
|
|
215
|
+
const audioContext = this._getAudioContext();
|
|
213
216
|
if (!this._audioSources) {
|
|
214
217
|
this._audioSources = [];
|
|
215
218
|
}
|
|
216
219
|
const gain = audioContext.createGain();
|
|
217
220
|
gain.connect(audioContext.destination);
|
|
218
|
-
gain.gain.value = soundsOptions.volume.value /
|
|
221
|
+
gain.gain.value = soundsOptions.volume.value / engine_1.percentDenominator;
|
|
219
222
|
this._gain = gain;
|
|
220
223
|
this._initEvents();
|
|
221
224
|
this._engine.dispatchEvent("soundsUnmuted", { container: this._container });
|
|
222
225
|
};
|
|
223
226
|
this._updateMuteIcons = () => {
|
|
224
|
-
const container = this._container,
|
|
227
|
+
const container = this._container, soundsOptions = container.actualOptions.sounds;
|
|
228
|
+
if (!soundsOptions?.enable || !soundsOptions.icons.enable) {
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
const muteImg = this._muteImg, unmuteImg = this._unmuteImg;
|
|
225
232
|
if (muteImg) {
|
|
226
233
|
muteImg.style.display = container.muted ? "block" : "none";
|
|
227
234
|
}
|
|
@@ -230,13 +237,13 @@
|
|
|
230
237
|
}
|
|
231
238
|
};
|
|
232
239
|
this._updateMuteStatus = async () => {
|
|
233
|
-
const container = this._container;
|
|
240
|
+
const container = this._container, audioContext = this._getAudioContext();
|
|
234
241
|
if (container.muted) {
|
|
235
|
-
await
|
|
236
|
-
this._mute();
|
|
242
|
+
await audioContext?.suspend();
|
|
243
|
+
await this._mute();
|
|
237
244
|
}
|
|
238
245
|
else {
|
|
239
|
-
await
|
|
246
|
+
await audioContext?.resume();
|
|
240
247
|
this._unmute();
|
|
241
248
|
this._playMuteSound();
|
|
242
249
|
}
|
|
@@ -248,12 +255,12 @@
|
|
|
248
255
|
}
|
|
249
256
|
(0, engine_1.clamp)(this._volume, soundsOptions.volume.min, soundsOptions.volume.max);
|
|
250
257
|
let stateChanged = false;
|
|
251
|
-
if (this._volume <=
|
|
258
|
+
if (this._volume <= minVolume && !container.muted) {
|
|
252
259
|
this._volume = 0;
|
|
253
260
|
container.muted = true;
|
|
254
261
|
stateChanged = true;
|
|
255
262
|
}
|
|
256
|
-
else if (this._volume >
|
|
263
|
+
else if (this._volume > minVolume && container.muted) {
|
|
257
264
|
container.muted = false;
|
|
258
265
|
stateChanged = true;
|
|
259
266
|
}
|
|
@@ -262,7 +269,7 @@
|
|
|
262
269
|
await this._updateMuteStatus();
|
|
263
270
|
}
|
|
264
271
|
if (this._gain?.gain) {
|
|
265
|
-
this._gain.gain.value = this._volume /
|
|
272
|
+
this._gain.gain.value = this._volume / engine_1.percentDenominator;
|
|
266
273
|
}
|
|
267
274
|
};
|
|
268
275
|
this._container = container;
|
|
@@ -276,6 +283,20 @@
|
|
|
276
283
|
if (!soundsOptions?.enable) {
|
|
277
284
|
return;
|
|
278
285
|
}
|
|
286
|
+
if (soundsOptions.autoPlay && (0, utils_js_1.isWindowMuted)()) {
|
|
287
|
+
const firstClickHandler = () => {
|
|
288
|
+
removeEventListener(engine_1.mouseDownEvent, firstClickHandler);
|
|
289
|
+
removeEventListener(engine_1.touchStartEvent, firstClickHandler);
|
|
290
|
+
(0, utils_js_1.unmuteWindow)();
|
|
291
|
+
void this.unmute();
|
|
292
|
+
};
|
|
293
|
+
const listenerOptions = {
|
|
294
|
+
capture: true,
|
|
295
|
+
once: true,
|
|
296
|
+
};
|
|
297
|
+
addEventListener(engine_1.mouseDownEvent, firstClickHandler, listenerOptions);
|
|
298
|
+
addEventListener(engine_1.touchStartEvent, firstClickHandler, listenerOptions);
|
|
299
|
+
}
|
|
279
300
|
this._volume = soundsOptions.volume.value;
|
|
280
301
|
const events = soundsOptions.events;
|
|
281
302
|
this._audioMap = new Map();
|
|
@@ -283,16 +304,25 @@
|
|
|
283
304
|
if (!event.audio) {
|
|
284
305
|
continue;
|
|
285
306
|
}
|
|
286
|
-
(0, engine_1.executeOnSingleOrMultiple)(event.audio, async (audio) => {
|
|
307
|
+
const promises = (0, engine_1.executeOnSingleOrMultiple)(event.audio, async (audio) => {
|
|
287
308
|
const response = await fetch(audio.source);
|
|
288
309
|
if (!response.ok) {
|
|
289
310
|
return;
|
|
290
311
|
}
|
|
291
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
292
|
-
container.audioContext = new AudioContext();
|
|
293
|
-
const audioBuffer = await container.audioContext.decodeAudioData(arrayBuffer);
|
|
312
|
+
const arrayBuffer = await response.arrayBuffer(), audioContext = this._getAudioContext(), audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
|
|
294
313
|
this._audioMap.set(audio.source, audioBuffer);
|
|
295
314
|
});
|
|
315
|
+
if (promises instanceof Promise) {
|
|
316
|
+
await promises;
|
|
317
|
+
}
|
|
318
|
+
else {
|
|
319
|
+
await Promise.allSettled(promises);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
async mute() {
|
|
324
|
+
if (!this._container.muted) {
|
|
325
|
+
await this.toggleMute();
|
|
296
326
|
}
|
|
297
327
|
}
|
|
298
328
|
async start() {
|
|
@@ -304,17 +334,14 @@
|
|
|
304
334
|
const canvas = container.canvas.element, pos = {
|
|
305
335
|
top: canvas.offsetTop,
|
|
306
336
|
right: canvas.offsetLeft + canvas.offsetWidth,
|
|
307
|
-
}, { mute, unmute, volumeDown, volumeUp } = soundsOptions.icons, margin = 10
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
this._updateMuteIcons();
|
|
311
|
-
await this._updateMuteStatus();
|
|
312
|
-
};
|
|
337
|
+
}, { mute, unmute, volumeDown, volumeUp } = soundsOptions.icons, margin = 10, toggleMute = async () => {
|
|
338
|
+
await this.toggleMute();
|
|
339
|
+
}, enableIcons = soundsOptions.icons.enable, display = enableIcons ? "block" : "none";
|
|
313
340
|
this._muteImg = initImage({
|
|
314
341
|
container,
|
|
315
342
|
options,
|
|
316
343
|
pos,
|
|
317
|
-
display
|
|
344
|
+
display,
|
|
318
345
|
iconOptions: mute,
|
|
319
346
|
margin,
|
|
320
347
|
rightOffsets: [volumeDown.width, volumeUp.width],
|
|
@@ -334,42 +361,76 @@
|
|
|
334
361
|
container,
|
|
335
362
|
options,
|
|
336
363
|
pos,
|
|
337
|
-
display
|
|
364
|
+
display,
|
|
338
365
|
iconOptions: volumeDown,
|
|
339
366
|
margin,
|
|
340
367
|
rightOffsets: [volumeUp.width],
|
|
341
368
|
clickCb: async () => {
|
|
342
|
-
|
|
343
|
-
this._volume = 0;
|
|
344
|
-
}
|
|
345
|
-
this._volume -= soundsOptions.volume.step;
|
|
346
|
-
await this._updateVolume();
|
|
369
|
+
await this.volumeDown();
|
|
347
370
|
},
|
|
348
371
|
});
|
|
349
372
|
this._volumeUpImg = initImage({
|
|
350
373
|
container,
|
|
351
374
|
options,
|
|
352
375
|
pos,
|
|
353
|
-
display
|
|
376
|
+
display,
|
|
354
377
|
iconOptions: volumeUp,
|
|
355
378
|
margin,
|
|
356
379
|
rightOffsets: [],
|
|
357
380
|
clickCb: async () => {
|
|
358
|
-
|
|
359
|
-
this._volume = 0;
|
|
360
|
-
}
|
|
361
|
-
this._volume += soundsOptions.volume.step;
|
|
362
|
-
await this._updateVolume();
|
|
381
|
+
await this.volumeUp();
|
|
363
382
|
},
|
|
364
383
|
});
|
|
384
|
+
if (!(0, utils_js_1.isWindowMuted)() && soundsOptions.autoPlay) {
|
|
385
|
+
await this.unmute();
|
|
386
|
+
}
|
|
365
387
|
}
|
|
366
388
|
stop() {
|
|
367
389
|
this._container.muted = true;
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
390
|
+
void (async () => {
|
|
391
|
+
await this._mute();
|
|
392
|
+
removeImage(this._muteImg);
|
|
393
|
+
removeImage(this._unmuteImg);
|
|
394
|
+
removeImage(this._volumeDownImg);
|
|
395
|
+
removeImage(this._volumeUpImg);
|
|
396
|
+
})();
|
|
397
|
+
}
|
|
398
|
+
async toggleMute() {
|
|
399
|
+
const container = this._container;
|
|
400
|
+
container.muted = !container.muted;
|
|
401
|
+
this._updateMuteIcons();
|
|
402
|
+
await this._updateMuteStatus();
|
|
403
|
+
}
|
|
404
|
+
async unmute() {
|
|
405
|
+
if (this._container.muted) {
|
|
406
|
+
await this.toggleMute();
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
async volumeDown() {
|
|
410
|
+
const container = this._container, soundsOptions = container.actualOptions.sounds;
|
|
411
|
+
if (!soundsOptions?.enable) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
if (container.muted) {
|
|
415
|
+
this._volume = 0;
|
|
416
|
+
}
|
|
417
|
+
this._volume -= soundsOptions.volume.step;
|
|
418
|
+
await this._updateVolume();
|
|
419
|
+
}
|
|
420
|
+
async volumeUp() {
|
|
421
|
+
const container = this._container, soundsOptions = container.actualOptions.sounds;
|
|
422
|
+
if (!soundsOptions?.enable) {
|
|
423
|
+
return;
|
|
424
|
+
}
|
|
425
|
+
this._volume += soundsOptions.volume.step;
|
|
426
|
+
await this._updateVolume();
|
|
427
|
+
}
|
|
428
|
+
_getAudioContext() {
|
|
429
|
+
const container = this._container;
|
|
430
|
+
if (!container.audioContext) {
|
|
431
|
+
container.audioContext = new AudioContext();
|
|
432
|
+
}
|
|
433
|
+
return container.audioContext;
|
|
373
434
|
}
|
|
374
435
|
}
|
|
375
436
|
exports.SoundsInstance = SoundsInstance;
|
package/umd/index.js
CHANGED
|
@@ -4,18 +4,31 @@
|
|
|
4
4
|
if (v !== undefined) module.exports = v;
|
|
5
5
|
}
|
|
6
6
|
else if (typeof define === "function" && define.amd) {
|
|
7
|
-
define(["require", "exports", "./Options/Classes/Sounds.js", "./SoundsInstance.js"], factory);
|
|
7
|
+
define(["require", "exports", "@tsparticles/engine", "./Options/Classes/Sounds.js", "./SoundsInstance.js", "./utils.js"], factory);
|
|
8
8
|
}
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.loadSoundsPlugin = void 0;
|
|
13
|
+
const engine_1 = require("@tsparticles/engine");
|
|
13
14
|
const Sounds_js_1 = require("./Options/Classes/Sounds.js");
|
|
14
15
|
const SoundsInstance_js_1 = require("./SoundsInstance.js");
|
|
16
|
+
const utils_js_1 = require("./utils.js");
|
|
17
|
+
const generalFirstClickHandler = () => {
|
|
18
|
+
removeEventListener(engine_1.mouseDownEvent, generalFirstClickHandler);
|
|
19
|
+
removeEventListener(engine_1.touchStartEvent, generalFirstClickHandler);
|
|
20
|
+
(0, utils_js_1.unmuteWindow)();
|
|
21
|
+
};
|
|
15
22
|
class SoundsPlugin {
|
|
16
23
|
constructor(engine) {
|
|
17
24
|
this.id = "sounds";
|
|
18
25
|
this._engine = engine;
|
|
26
|
+
const listenerOptions = {
|
|
27
|
+
capture: true,
|
|
28
|
+
once: true,
|
|
29
|
+
};
|
|
30
|
+
addEventListener(engine_1.mouseDownEvent, generalFirstClickHandler, listenerOptions);
|
|
31
|
+
addEventListener(engine_1.touchStartEvent, generalFirstClickHandler, listenerOptions);
|
|
19
32
|
}
|
|
20
33
|
getPlugin(container) {
|
|
21
34
|
return new SoundsInstance_js_1.SoundsInstance(container, this._engine);
|
package/umd/utils.js
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
})(function (require, exports) {
|
|
10
10
|
"use strict";
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.getNoteFrequency = void 0;
|
|
12
|
+
exports.unmuteWindow = exports.isWindowMuted = exports.getNoteFrequency = void 0;
|
|
13
13
|
const notes = new Map();
|
|
14
14
|
notes.set("C", [16.35, 32.7, 65.41, 130.81, 261.63, 523.25, 1046.5, 2093.0, 4186.01]);
|
|
15
15
|
notes.set("Db", [17.32, 34.65, 69.3, 138.59, 277.18, 554.37, 1108.73, 2217.46, 4434.92]);
|
|
@@ -25,15 +25,24 @@
|
|
|
25
25
|
notes.set("B", [30.87, 61.74, 123.47, 246.94, 493.88, 987.77, 1975.53, 3951.07, 7902.13]);
|
|
26
26
|
notes.set("pause", [0]);
|
|
27
27
|
function getNoteFrequency(note) {
|
|
28
|
-
const regex = /(([A-G]b?)(\d))|pause/i, result = regex.exec(note);
|
|
29
|
-
if (!result
|
|
28
|
+
const regex = /(([A-G]b?)(\d))|pause/i, result = regex.exec(note), groupKey = 2, defaultMatchKey = 0, innerGroupKey = 3;
|
|
29
|
+
if (!result?.length) {
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
|
-
const noteKey = result[
|
|
32
|
+
const noteKey = result[groupKey] || result[defaultMatchKey], noteItem = notes.get(noteKey);
|
|
33
33
|
if (!noteItem) {
|
|
34
34
|
return;
|
|
35
35
|
}
|
|
36
|
-
return noteItem[parseInt(result[
|
|
36
|
+
return noteItem[parseInt(result[innerGroupKey] || "0")];
|
|
37
37
|
}
|
|
38
38
|
exports.getNoteFrequency = getNoteFrequency;
|
|
39
|
+
let muted = true;
|
|
40
|
+
const isWindowMuted = () => {
|
|
41
|
+
return muted;
|
|
42
|
+
};
|
|
43
|
+
exports.isWindowMuted = isWindowMuted;
|
|
44
|
+
const unmuteWindow = () => {
|
|
45
|
+
muted = false;
|
|
46
|
+
};
|
|
47
|
+
exports.unmuteWindow = unmuteWindow;
|
|
39
48
|
});
|