@tsparticles/plugin-sounds 3.9.1 → 4.0.0-alpha.1

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 (44) hide show
  1. package/902.min.js +2 -0
  2. package/902.min.js.LICENSE.txt +1 -0
  3. package/browser/Options/Classes/SoundsEvent.js +1 -1
  4. package/browser/SoundsInstance.js +26 -24
  5. package/browser/index.js +6 -4
  6. package/browser/utils.js +2 -2
  7. package/cjs/Options/Classes/Sounds.js +9 -13
  8. package/cjs/Options/Classes/SoundsAudio.js +4 -8
  9. package/cjs/Options/Classes/SoundsEvent.js +14 -18
  10. package/cjs/Options/Classes/SoundsIcon.js +3 -7
  11. package/cjs/Options/Classes/SoundsIcons.js +8 -12
  12. package/cjs/Options/Classes/SoundsMelody.js +5 -9
  13. package/cjs/Options/Classes/SoundsNote.js +3 -7
  14. package/cjs/Options/Classes/SoundsVolume.js +4 -8
  15. package/cjs/Options/Interfaces/ISounds.js +1 -2
  16. package/cjs/Options/Interfaces/ISoundsAudio.js +1 -2
  17. package/cjs/Options/Interfaces/ISoundsEvent.js +1 -2
  18. package/cjs/Options/Interfaces/ISoundsIcon.js +1 -2
  19. package/cjs/Options/Interfaces/ISoundsIcons.js +1 -2
  20. package/cjs/Options/Interfaces/ISoundsMelody.js +1 -2
  21. package/cjs/Options/Interfaces/ISoundsNote.js +1 -2
  22. package/cjs/Options/Interfaces/ISoundsVolume.js +1 -2
  23. package/cjs/SoundsInstance.js +53 -55
  24. package/cjs/SoundsPlugin.js +12 -16
  25. package/cjs/enums.js +4 -7
  26. package/cjs/index.js +6 -7
  27. package/cjs/types.js +1 -2
  28. package/cjs/utils.js +5 -11
  29. package/dist_browser_SoundsPlugin_js.js +140 -0
  30. package/esm/Options/Classes/SoundsEvent.js +1 -1
  31. package/esm/SoundsInstance.js +26 -24
  32. package/esm/index.js +6 -4
  33. package/esm/utils.js +2 -2
  34. package/package.json +4 -3
  35. package/report.html +5 -4
  36. package/tsparticles.plugin.sounds.js +209 -140
  37. package/tsparticles.plugin.sounds.min.js +1 -1
  38. package/tsparticles.plugin.sounds.min.js.LICENSE.txt +1 -1
  39. package/types/SoundsInstance.d.ts +1 -1
  40. package/types/index.d.ts +1 -1
  41. package/umd/Options/Classes/SoundsEvent.js +1 -1
  42. package/umd/SoundsInstance.js +25 -23
  43. package/umd/index.js +41 -5
  44. package/umd/utils.js +2 -2
package/902.min.js ADDED
@@ -0,0 +1,2 @@
1
+ /*! For license information please see 902.min.js.LICENSE.txt */
2
+ (this.webpackChunk_tsparticles_plugin_sounds=this.webpackChunk_tsparticles_plugin_sounds||[]).push([[902],{902(t,e,i){i.d(e,{SoundsPlugin:()=>b});var s,n,o=i(303);class a{constructor(){this.loop=!1,this.source=""}load(t){(0,o.isNull)(t)||((0,o.isObject)(t)?(void 0!==t.loop&&(this.loop=t.loop),void 0!==t.source&&(this.source=t.source)):this.source=t)}}class u{constructor(){this.duration=500,this.value=[]}load(t){(0,o.isNull)(t)||(void 0!==t.duration&&(this.duration=t.duration),void 0!==t.value&&(this.value=t.value))}}class l{constructor(){this.loop=!1,this.melodies=[],this.notes=[]}load(t){(0,o.isNull)(t)||(void 0!==t.loop&&(this.loop=t.loop),void 0!==t.melodies&&(this.melodies=t.melodies.map((t=>{const e=new l;return e.load(t),e}))),void 0!==t.notes&&(this.notes=t.notes.map((t=>{const e=new u;return e.load(t),e}))))}}class c{constructor(){this.event=[],this.notes=[]}load(t){if(!(0,o.isNull)(t)&&(void 0!==t.event&&(this.event=t.event),void 0!==t.audio&&((0,o.isArray)(t.audio)?this.audio=t.audio.map((t=>{const e=new a;return e.load(t),e})):(this.audio=new a,this.audio.load(t.audio))),void 0!==t.notes&&(this.notes=t.notes.map((t=>{const e=new u;return e.load(t),e}))),void 0!==t.melodies&&(this.melodies=t.melodies.map((t=>{const e=new l;return e.load(t),e}))),t.filter))if((0,o.isString)(t.filter)){const e=globalThis[t.filter];(0,o.isFunction)(e)&&(this.filter=e)}else this.filter=t.filter}}class r{constructor(){this.width=24,this.height=24,this.style=""}load(t){(0,o.isNull)(t)||(void 0!==t.path&&(this.path=t.path),void 0!==t.svg&&(this.svg=t.svg),void 0!==t.width&&(this.width=t.width),void 0!==t.height&&(this.height=t.height))}}class h{constructor(){this.mute=new r,this.unmute=new r,this.volumeDown=new r,this.volumeUp=new r,this.enable=!1,this.mute.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M19.707,5.293c-0.391-0.391-1.023-0.391-1.414,0l-1.551,1.551c-0.345-0.688-0.987-1.02-1.604-1.02c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.237,0.754,2.302,1.826,2.76l-1.533,1.533c-0.391,0.391-0.391,1.023,0,1.414C5.488,19.902,5.744,20,6,20s0.512-0.098,0.707-0.293l2.527-2.527c0.697,0.174,1.416,0.455,1.875,0.762l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V9.414l2.707-2.707C20.098,6.316,20.098,5.684,19.707,5.293z M14.891,7.941c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8v1.293l-2,2V9.202L14.891,7.941z M7,12c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v2.439l-2.83,2.83C8.757,15.046,8.356,15,8,15c-0.552,0-1-0.448-1-1V12z M10.301,15.406L12,13.707v2.439C11.519,15.859,10.925,15.604,10.301,15.406z M14.994,18.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798v-4.091l2-2V18C15,18.046,14.998,18.086,14.994,18.12z"/>\n </g>\n</svg>',this.unmute.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M17.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C12.357,8.561,10.904,9,10,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C18.035,20.176,19,19.495,19,18V8C19,6.505,18.035,5.824,17.138,5.824z M14,16.146C12.907,15.495,11.211,15,10,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146V16.146z M17,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L15,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C16.998,7.914,17,7.954,17,8V18z"/>\n </g>\n</svg>',this.volumeDown.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M15.138,5.824c-0.449,0-0.905,0.152-1.356,0.453l-2.672,1.781C10.357,8.561,8.904,9,8,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C16.035,20.176,17,19.495,17,18V8C17,6.505,16.035,5.824,15.138,5.824z M8,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C10.907,15.495,9.211,15,8,15z M15,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L13,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C14.998,7.914,15,7.954,15,8V18z"/>\n <path fill="#fff" d="M18.292,10.294c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C18.488,15.902,18.744,16,19,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708s-0.398-1.984-1.123-2.707C19.317,9.903,18.683,9.901,18.292,10.294z"/>\n </g>\n</svg>',this.volumeUp.svg='<?xml version="1.0"?>\n<svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"\n xml:space="preserve" xmlns="http://www.w3.org/2000/svg"\n xmlns:xlink="http://www.w3.org/1999/xlink">\n <g id="Layer_1">\n <path fill="#fff" d="M16.706,10.292c-0.389-0.389-1.023-0.391-1.414,0.002c-0.39,0.391-0.39,1.023,0.002,1.414c0.345,0.345,0.535,0.803,0.535,1.291c0,0.489-0.19,0.948-0.536,1.294c-0.391,0.39-0.391,1.023,0,1.414C15.488,15.902,15.744,16,16,16s0.512-0.098,0.707-0.293c0.724-0.723,1.122-1.685,1.122-2.708S17.431,11.015,16.706,10.292z"/>\n <path fill="#fff" d="M18.706,8.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c0.879,0.877,1.363,2.044,1.364,3.287c0.001,1.246-0.484,2.417-1.365,3.298c-0.391,0.391-0.391,1.023,0,1.414C17.488,17.902,17.744,18,18,18s0.512-0.098,0.707-0.293c1.259-1.259,1.952-2.933,1.951-4.713C20.657,11.217,19.964,9.547,18.706,8.292z"/>\n <path fill="#fff" d="M20.706,6.292c-0.391-0.389-1.023-0.39-1.414,0.002c-0.39,0.391-0.39,1.024,0.002,1.414c1.412,1.409,2.191,3.285,2.192,5.284c0.002,2.002-0.777,3.885-2.193,5.301c-0.391,0.391-0.391,1.023,0,1.414C19.488,19.902,19.744,20,20,20s0.512-0.098,0.707-0.293c1.794-1.794,2.781-4.18,2.779-6.717C23.485,10.457,22.497,8.078,20.706,6.292z"/>\n <path fill="#fff" d="M12.138,5.824c-0.449,0-0.905,0.152-1.356,0.453L8.109,8.059C7.357,8.561,5.904,9,5,9c-1.654,0-3,1.346-3,3v2c0,1.654,1.346,3,3,3c0.904,0,2.357,0.439,3.109,0.941l2.672,1.781c0.451,0.301,0.907,0.453,1.356,0.453C13.035,20.176,14,19.495,14,18V8C14,6.505,13.035,5.824,12.138,5.824z M5,15c-0.552,0-1-0.448-1-1v-2c0-0.552,0.448-1,1-1c1.211,0,2.907-0.495,4-1.146v6.293C7.907,15.495,6.211,15,5,15z M12,18c0,0.046-0.002,0.086-0.006,0.12c-0.03-0.016-0.065-0.036-0.104-0.062L10,16.798V9.202l1.891-1.261c0.038-0.025,0.073-0.046,0.104-0.062C11.998,7.914,12,7.954,12,8V18z"/>\n </g>\n</svg>'}load(t){(0,o.isNull)(t)||(void 0!==t.enable&&(this.enable=t.enable),this.mute.load(t.mute),this.unmute.load(t.unmute),this.volumeDown.load(t.volumeDown),this.volumeUp.load(t.volumeUp))}}class d{constructor(){this.value=100,this.max=100,this.min=0,this.step=10}load(t){(0,o.isNull)(t)||((0,o.isObject)(t)?(void 0!==t.max&&(this.max=t.max),void 0!==t.min&&(this.min=t.min),void 0!==t.step&&(this.step=t.step),void 0!==t.value&&(this.value=t.value)):this.value=t)}}class m{constructor(){this.autoPlay=!0,this.enable=!1,this.events=[],this.icons=new h,this.volume=new d}load(t){(0,o.isNull)(t)||(void 0!==t.autoPlay&&(this.autoPlay=t.autoPlay),void 0!==t.enable&&(this.enable=t.enable),void 0!==t.events&&(this.events=t.events.map((t=>{const e=new c;return e.load(t),e}))),this.icons.load(t.icons),void 0!==t.volume&&this.volume.load(t.volume))}}!function(t){t.mute="soundsMuted",t.unmute="soundsUnmuted"}(s||(s={})),function(t){t.Block="block",t.None="none"}(n||(n={}));const v=new Map;function p(t){const e=/(([A-G]b?)(\d))|pause/i.exec(t);if(!e?.length)return;const i=e[2]??e[0],s=v.get(i);return s?s[parseInt(e[3]??"0")]:void 0}v.set("C",[16.35,32.7,65.41,130.81,261.63,523.25,1046.5,2093,4186.01]),v.set("Db",[17.32,34.65,69.3,138.59,277.18,554.37,1108.73,2217.46,4434.92]),v.set("D",[18.35,36.71,73.42,146.83,293.66,587.33,1174.66,2349.32,4698.63]),v.set("Eb",[19.45,38.89,77.78,155.56,311.13,622.25,1244.51,2489.02,4978.03]),v.set("E",[20.6,41.2,82.41,164.81,329.63,659.25,1318.51,2637.02,5274.04]),v.set("F",[21.83,43.65,87.31,174.61,349.23,698.46,1396.91,2793.83,5587.65]),v.set("Gb",[23.12,46.25,92.5,185,369.99,739.99,1479.98,2959.96,5919.91]),v.set("G",[24.5,49,98,196,392,783.99,1567.98,3135.96,6271.93]),v.set("Ab",[25.96,51.91,103.83,207.65,415.3,830.61,1661.22,3322.44,6644.88]),v.set("A",[27.5,55,110,220,440,880,1760,3520,7040]),v.set("Bb",[29.14,58.27,116.54,233.08,466.16,932.33,1864.66,3729.31,7458.62]),v.set("B",[30.87,61.74,123.47,246.94,493.88,987.77,1975.53,3951.07,7902.13]),v.set("pause",[0]);let g=!0;const f=()=>g,_=()=>{g=!1};function w(t){const e=(0,o.safeDocument)().createElement("img"),{clickCb:i,container:s,display:n,iconOptions:a,margin:u,options:l,pos:c,rightOffsets:r}=t,{width:h,path:d,style:m,svg:v}=a;!function(t,e,i,s,n,o,a,u){t.style.userSelect="none",t.style.position="absolute",t.style.top=`${(e+a).toString()}px`,t.style.left=`${(i-a-o).toString()}px`,t.style.display=s,t.style.zIndex=(n+1).toString(),t.style.cssText+=u}(e,c.top+u,c.right-(u*(r.length+1)+h+r.reduce(((t,e)=>t+e),0)),n,l.fullScreen.zIndex+1,h,u,m),e.src=d??(v?`data:image/svg+xml;base64,${btoa(v)}`:"");return(s.canvas.element?.parentNode??(0,o.safeDocument)().body).append(e),e.addEventListener("click",(()=>{i()})),e}function y(t){t&&t.remove()}class x{constructor(t,e){this._addBuffer=t=>{const e=t.createBufferSource();return this._audioSources.push(e),e},this._addOscillator=t=>{const e=t.createOscillator();return this._audioSources.push(e),e},this._initEvents=()=>{const t=this._container,e=t.actualOptions.sounds;if(e?.enable&&t.canvas.element)for(const t of e.events){const e=i=>{(async()=>{const s=t.filter&&!t.filter(i);if(this._container!==i.container)return;if(this._container.muted||this._container.destroyed)return void(0,o.executeOnSingleOrMultiple)(t.event,(t=>{this._engine.removeEventListener(t,e)}));if(s)return;if(t.audio){const e=(0,o.itemFromSingleOrMultiple)(t.audio);if(!e)return;this._playBuffer(e)}else if(t.melodies){const e=(0,o.itemFromArray)(t.melodies);if(!e)return;e.melodies.length?await Promise.allSettled(e.melodies.map((t=>this._playNote(t.notes,0,e.loop)))):await this._playNote(e.notes,0,e.loop)}else if(t.notes){const e=(0,o.itemFromArray)(t.notes);if(!e)return;await this._playNote([e],0,!1)}})()};(0,o.executeOnSingleOrMultiple)(t.event,(t=>{this._engine.addEventListener(t,e)}))}},this._mute=async()=>{const t=this._container,e=this._getAudioContext();for(const t of this._audioSources)this._removeAudioSource(t);this._gain&&this._gain.disconnect(),await e.close(),t.audioContext=void 0,this._engine.dispatchEvent(s.mute,{container:this._container})},this._playBuffer=t=>{const e=this._audioMap.get(t.source);if(!e)return;const i=this._container.audioContext;if(!i)return;const s=this._addBuffer(i);s.loop=t.loop,s.buffer=e,s.connect(this._gain??i.destination),s.start()},this._playFrequency=async(t,e)=>{if(!this._gain||this._container.muted)return;const i=this._getAudioContext(),s=this._addOscillator(i);return s.connect(this._gain),s.type="sine",s.frequency.value=t,s.start(),new Promise((t=>{setTimeout((()=>{this._removeAudioSource(s),t()}),e)}))},this._playMuteSound=()=>{if(this._container.muted)return;const t=this._getAudioContext(),e=t.createGain();e.connect(t.destination),e.gain.value=0;const i=t.createOscillator();i.connect(e),i.type="sine",i.frequency.value=1,i.start(),setTimeout((()=>{i.stop(),i.disconnect(),e.disconnect()}))},this._playNote=async(t,e,i)=>{if(this._container.muted)return;const s=t[e];if(!s)return;const n=s.value,a=(0,o.executeOnSingleOrMultiple)(n,(async(i,s)=>this._playNoteValue(t,e,s)));await((0,o.isArray)(a)?Promise.allSettled(a):a);let u=e+1;i&&u>=t.length&&(u%=t.length),await this._playNote(t,u,i)},this._playNoteValue=async(t,e,i)=>{const s=t[e];if(!s)return;const n=(0,o.itemFromSingleOrMultiple)(s.value,i,!0);if(n)try{const t=p(n);if(!(0,o.isNumber)(t))return;await this._playFrequency(t,s.duration)}catch(t){(0,o.getLogger)().error(t)}},this._removeAudioSource=t=>{t.stop(),t.disconnect();this._audioSources.splice(this._audioSources.indexOf(t),1)},this._unmute=()=>{const t=this._container.actualOptions.sounds;if(!t)return;const e=this._getAudioContext(),i=e.createGain();i.connect(e.destination),i.gain.value=t.volume.value/o.percentDenominator,this._gain=i,this._initEvents(),this._engine.dispatchEvent(s.unmute,{container:this._container})},this._updateMuteIcons=()=>{const t=this._container,e=t.actualOptions.sounds;if(!e?.enable||!e.icons.enable)return;const i=this._muteImg,s=this._unmuteImg;i&&(i.style.display=t.muted?"block":"none"),s&&(s.style.display=t.muted?"none":"block")},this._updateMuteStatus=async()=>{const t=this._container,e=this._getAudioContext();t.muted?(await e.suspend(),await this._mute()):(await e.resume(),this._unmute(),this._playMuteSound())},this._updateVolume=async()=>{const t=this._container,e=t.actualOptions.sounds;if(!e?.enable)return;(0,o.clamp)(this._volume,e.volume.min,e.volume.max);let i=!1;this._volume<=0&&!t.muted?(this._volume=0,t.muted=!0,i=!0):this._volume>0&&t.muted&&(t.muted=!1,i=!0),i&&(this._updateMuteIcons(),await this._updateMuteStatus()),this._gain?.gain&&(this._gain.gain.value=this._volume/o.percentDenominator)},this._container=t,this._engine=e,this._volume=0,this._audioSources=[],this._audioMap=new Map}async init(){const t=this._container.actualOptions.sounds;if(!t?.enable)return;if(t.autoPlay&&f()){const t=()=>{removeEventListener(o.mouseDownEvent,t),removeEventListener(o.touchStartEvent,t),_(),this.unmute()},e={capture:!0,once:!0};addEventListener(o.mouseDownEvent,t,e),addEventListener(o.touchStartEvent,t,e)}this._volume=t.volume.value;const e=t.events;this._audioMap=new Map;for(const t of e){if(!t.audio)continue;const e=(0,o.executeOnSingleOrMultiple)(t.audio,(async t=>{const e=await fetch(t.source);if(!e.ok)return;const i=await e.arrayBuffer(),s=this._getAudioContext(),n=await s.decodeAudioData(i);this._audioMap.set(t.source,n)}));e instanceof Promise?await e:await Promise.allSettled(e)}}async mute(){this._container.muted||await this.toggleMute()}async start(){const t=this._container,e=t.actualOptions,i=e.sounds;if(!i?.enable||!t.canvas.element)return;t.muted=!0;const s=t.canvas.element,o={top:s.offsetTop,right:s.offsetLeft+s.offsetWidth},{mute:a,unmute:u,volumeDown:l,volumeUp:c}=i.icons,r=async()=>{await this.toggleMute()},h=i.icons.enable?n.Block:n.None;this._muteImg=w({container:t,options:e,pos:o,display:h,iconOptions:a,margin:10,rightOffsets:[l.width,c.width],clickCb:r}),this._unmuteImg=w({container:t,options:e,pos:o,display:n.None,iconOptions:u,margin:10,rightOffsets:[l.width,c.width],clickCb:r}),this._volumeDownImg=w({container:t,options:e,pos:o,display:h,iconOptions:l,margin:10,rightOffsets:[c.width],clickCb:async()=>{await this.volumeDown()}}),this._volumeUpImg=w({container:t,options:e,pos:o,display:h,iconOptions:c,margin:10,rightOffsets:[],clickCb:async()=>{await this.volumeUp()}}),!f()&&i.autoPlay&&await this.unmute()}stop(){this._container.muted=!0,(async()=>{await this._mute(),y(this._muteImg),y(this._unmuteImg),y(this._volumeDownImg),y(this._volumeUpImg)})()}async toggleMute(){const t=this._container;t.muted=!t.muted,this._updateMuteIcons(),await this._updateMuteStatus()}async unmute(){this._container.muted&&await this.toggleMute()}async volumeDown(){const t=this._container,e=t.actualOptions.sounds;e?.enable&&(t.muted&&(this._volume=0),this._volume-=e.volume.step,await this._updateVolume())}async volumeUp(){const t=this._container.actualOptions.sounds;t?.enable&&(this._volume+=t.volume.step,await this._updateVolume())}_getAudioContext(){const t=this._container;return t.audioContext??=new AudioContext,t.audioContext}}const C=()=>{removeEventListener(o.mouseDownEvent,C),removeEventListener(o.touchStartEvent,C),_()};class b{constructor(t){this.id="sounds",this._engine=t;const e={capture:!0,once:!0};addEventListener(o.mouseDownEvent,C,e),addEventListener(o.touchStartEvent,C,e)}getPlugin(t){return Promise.resolve(new x(t,this._engine))}loadOptions(t,e){if(!this.needsPlugin(t)&&!this.needsPlugin(e))return;let i=t.sounds;void 0===i?.load&&(t.sounds=i=new m),i.load(e?.sounds)}needsPlugin(t){return t?.sounds?.enable??!1}}}}]);
@@ -0,0 +1 @@
1
+ /*! tsParticles Sounds Plugin v4.0.0-alpha.1 by Matteo Bruni */
@@ -43,7 +43,7 @@ export class SoundsEvent {
43
43
  }
44
44
  if (data.filter) {
45
45
  if (isString(data.filter)) {
46
- const filterFunc = window[data.filter];
46
+ const filterFunc = globalThis[data.filter];
47
47
  if (isFunction(filterFunc)) {
48
48
  this.filter = filterFunc;
49
49
  }
@@ -1,15 +1,15 @@
1
- import { clamp, executeOnSingleOrMultiple, getLogger, isArray, isNumber, itemFromArray, itemFromSingleOrMultiple, mouseDownEvent, percentDenominator, touchStartEvent, } from "@tsparticles/engine";
1
+ import { clamp, executeOnSingleOrMultiple, getLogger, isArray, isNumber, itemFromArray, itemFromSingleOrMultiple, mouseDownEvent, percentDenominator, safeDocument, touchStartEvent, } from "@tsparticles/engine";
2
2
  import { ImageDisplay, SoundsEventType } from "./enums.js";
3
3
  import { getNoteFrequency, isWindowMuted, unmuteWindow } from "./utils.js";
4
4
  const zIndexOffset = 1, rightOffset = 1, minVolume = 0;
5
5
  function initImage(data) {
6
- const img = document.createElement("img"), { clickCb, container, display, iconOptions, margin, options, pos, rightOffsets } = data, { width, path, style, svg } = iconOptions, defaultAccumulator = 0;
6
+ const img = safeDocument().createElement("img"), { clickCb, container, display, iconOptions, margin, options, pos, rightOffsets } = data, { width, path, style, svg } = iconOptions, defaultAccumulator = 0;
7
7
  setIconStyle(img, pos.top + margin, pos.right -
8
8
  (margin * (rightOffsets.length + rightOffset) +
9
9
  width +
10
10
  rightOffsets.reduce((a, b) => a + b, defaultAccumulator)), display, options.fullScreen.zIndex + zIndexOffset, width, margin, style);
11
11
  img.src = path ?? (svg ? `data:image/svg+xml;base64,${btoa(svg)}` : "");
12
- const parent = container.canvas.element?.parentNode ?? document.body;
12
+ const parent = container.canvas.element?.parentNode ?? safeDocument().body;
13
13
  parent.append(img);
14
14
  img.addEventListener("click", () => {
15
15
  void clickCb();
@@ -24,12 +24,11 @@ function removeImage(image) {
24
24
  }
25
25
  function setIconStyle(icon, top, left, display, zIndex, width, margin, style) {
26
26
  icon.style.userSelect = "none";
27
- icon.style.webkitUserSelect = "none";
28
27
  icon.style.position = "absolute";
29
- icon.style.top = `${top + margin}px`;
30
- icon.style.left = `${left - margin - width}px`;
28
+ icon.style.top = `${(top + margin).toString()}px`;
29
+ icon.style.left = `${(left - margin - width).toString()}px`;
31
30
  icon.style.display = display;
32
- icon.style.zIndex = `${zIndex + zIndexOffset}`;
31
+ icon.style.zIndex = (zIndex + zIndexOffset).toString();
33
32
  icon.style.cssText += style;
34
33
  }
35
34
  export class SoundsInstance {
@@ -56,7 +55,7 @@ export class SoundsInstance {
56
55
  if (this._container !== args.container) {
57
56
  return;
58
57
  }
59
- if (!this._container || !!this._container.muted || this._container.destroyed) {
58
+ if (!!this._container.muted || this._container.destroyed) {
60
59
  executeOnSingleOrMultiple(event.event, item => {
61
60
  this._engine.removeEventListener(item, cb);
62
61
  });
@@ -67,10 +66,17 @@ export class SoundsInstance {
67
66
  }
68
67
  const defaultNoteIndex = 0;
69
68
  if (event.audio) {
70
- this._playBuffer(itemFromSingleOrMultiple(event.audio));
69
+ const audio = itemFromSingleOrMultiple(event.audio);
70
+ if (!audio) {
71
+ return;
72
+ }
73
+ this._playBuffer(audio);
71
74
  }
72
75
  else if (event.melodies) {
73
76
  const melody = itemFromArray(event.melodies);
77
+ if (!melody) {
78
+ return;
79
+ }
74
80
  if (melody.melodies.length) {
75
81
  await Promise.allSettled(melody.melodies.map(m => this._playNote(m.notes, defaultNoteIndex, melody.loop)));
76
82
  }
@@ -80,6 +86,9 @@ export class SoundsInstance {
80
86
  }
81
87
  else if (event.notes) {
82
88
  const note = itemFromArray(event.notes);
89
+ if (!note) {
90
+ return;
91
+ }
83
92
  await this._playNote([note], defaultNoteIndex, false);
84
93
  }
85
94
  })();
@@ -158,8 +167,7 @@ export class SoundsInstance {
158
167
  if (!note) {
159
168
  return;
160
169
  }
161
- const value = note.value;
162
- const promises = executeOnSingleOrMultiple(value, async (_, idx) => {
170
+ const value = note.value, promises = executeOnSingleOrMultiple(value, async (_, idx) => {
163
171
  return this._playNoteValue(notes, noteIdx, idx);
164
172
  });
165
173
  await (isArray(promises) ? Promise.allSettled(promises) : promises);
@@ -168,9 +176,6 @@ export class SoundsInstance {
168
176
  if (loop && nextNoteIdx >= notes.length) {
169
177
  nextNoteIdx = nextNoteIdx % notes.length;
170
178
  }
171
- if (this._container.muted) {
172
- return;
173
- }
174
179
  await this._playNote(notes, nextNoteIdx, loop);
175
180
  };
176
181
  this._playNoteValue = async (notes, noteIdx, valueIdx) => {
@@ -179,6 +184,9 @@ export class SoundsInstance {
179
184
  return;
180
185
  }
181
186
  const value = itemFromSingleOrMultiple(note.value, valueIdx, true);
187
+ if (!value) {
188
+ return;
189
+ }
182
190
  try {
183
191
  const freq = getNoteFrequency(value);
184
192
  if (!isNumber(freq)) {
@@ -201,11 +209,7 @@ export class SoundsInstance {
201
209
  if (!soundsOptions) {
202
210
  return;
203
211
  }
204
- const audioContext = this._getAudioContext();
205
- if (!this._audioSources) {
206
- this._audioSources = [];
207
- }
208
- const gain = audioContext.createGain();
212
+ const audioContext = this._getAudioContext(), gain = audioContext.createGain();
209
213
  gain.connect(audioContext.destination);
210
214
  gain.gain.value = soundsOptions.volume.value / percentDenominator;
211
215
  this._gain = gain;
@@ -228,11 +232,11 @@ export class SoundsInstance {
228
232
  this._updateMuteStatus = async () => {
229
233
  const container = this._container, audioContext = this._getAudioContext();
230
234
  if (container.muted) {
231
- await audioContext?.suspend();
235
+ await audioContext.suspend();
232
236
  await this._mute();
233
237
  }
234
238
  else {
235
- await audioContext?.resume();
239
+ await audioContext.resume();
236
240
  this._unmute();
237
241
  this._playMuteSound();
238
242
  }
@@ -416,9 +420,7 @@ export class SoundsInstance {
416
420
  }
417
421
  _getAudioContext() {
418
422
  const container = this._container;
419
- if (!container.audioContext) {
420
- container.audioContext = new AudioContext();
421
- }
423
+ container.audioContext ??= new AudioContext();
422
424
  return container.audioContext;
423
425
  }
424
426
  }
package/browser/index.js CHANGED
@@ -1,5 +1,7 @@
1
- import { SoundsPlugin } from "./SoundsPlugin.js";
2
- export async function loadSoundsPlugin(engine, refresh = true) {
3
- engine.checkVersion("3.9.1");
4
- await engine.addPlugin(new SoundsPlugin(engine), refresh);
1
+ export function loadSoundsPlugin(engine) {
2
+ engine.checkVersion("4.0.0-alpha.1");
3
+ engine.register(async (e) => {
4
+ const { SoundsPlugin } = await import("./SoundsPlugin.js");
5
+ e.addPlugin(new SoundsPlugin(engine));
6
+ });
5
7
  }
package/browser/utils.js CHANGED
@@ -17,11 +17,11 @@ export function getNoteFrequency(note) {
17
17
  if (!result?.length) {
18
18
  return;
19
19
  }
20
- const noteKey = result[groupKey] || result[defaultMatchKey], noteItem = notes.get(noteKey);
20
+ const noteKey = result[groupKey] ?? result[defaultMatchKey], noteItem = notes.get(noteKey);
21
21
  if (!noteItem) {
22
22
  return;
23
23
  }
24
- return noteItem[parseInt(result[innerGroupKey] || "0")];
24
+ return noteItem[parseInt(result[innerGroupKey] ?? "0")];
25
25
  }
26
26
  let muted = true;
27
27
  export const isWindowMuted = () => {
@@ -1,20 +1,17 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.Sounds = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- const SoundsEvent_js_1 = require("./SoundsEvent.js");
6
- const SoundsIcons_js_1 = require("./SoundsIcons.js");
7
- const SoundsVolume_js_1 = require("./SoundsVolume.js");
8
- class Sounds {
1
+ import { isNull } from "@tsparticles/engine";
2
+ import { SoundsEvent } from "./SoundsEvent.js";
3
+ import { SoundsIcons } from "./SoundsIcons.js";
4
+ import { SoundsVolume } from "./SoundsVolume.js";
5
+ export class Sounds {
9
6
  constructor() {
10
7
  this.autoPlay = true;
11
8
  this.enable = false;
12
9
  this.events = [];
13
- this.icons = new SoundsIcons_js_1.SoundsIcons();
14
- this.volume = new SoundsVolume_js_1.SoundsVolume();
10
+ this.icons = new SoundsIcons();
11
+ this.volume = new SoundsVolume();
15
12
  }
16
13
  load(data) {
17
- if ((0, engine_1.isNull)(data)) {
14
+ if (isNull(data)) {
18
15
  return;
19
16
  }
20
17
  if (data.autoPlay !== undefined) {
@@ -25,7 +22,7 @@ class Sounds {
25
22
  }
26
23
  if (data.events !== undefined) {
27
24
  this.events = data.events.map(t => {
28
- const event = new SoundsEvent_js_1.SoundsEvent();
25
+ const event = new SoundsEvent();
29
26
  event.load(t);
30
27
  return event;
31
28
  });
@@ -36,4 +33,3 @@ class Sounds {
36
33
  }
37
34
  }
38
35
  }
39
- exports.Sounds = Sounds;
@@ -1,17 +1,14 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsAudio = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- class SoundsAudio {
1
+ import { isNull, isObject } from "@tsparticles/engine";
2
+ export class SoundsAudio {
6
3
  constructor() {
7
4
  this.loop = false;
8
5
  this.source = "";
9
6
  }
10
7
  load(data) {
11
- if ((0, engine_1.isNull)(data)) {
8
+ if (isNull(data)) {
12
9
  return;
13
10
  }
14
- if ((0, engine_1.isObject)(data)) {
11
+ if (isObject(data)) {
15
12
  if (data.loop !== undefined) {
16
13
  this.loop = data.loop;
17
14
  }
@@ -24,4 +21,3 @@ class SoundsAudio {
24
21
  }
25
22
  }
26
23
  }
27
- exports.SoundsAudio = SoundsAudio;
@@ -1,53 +1,50 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsEvent = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- const SoundsAudio_js_1 = require("./SoundsAudio.js");
6
- const SoundsMelody_js_1 = require("./SoundsMelody.js");
7
- const SoundsNote_js_1 = require("./SoundsNote.js");
8
- class SoundsEvent {
1
+ import { isArray, isFunction, isNull, isString, } from "@tsparticles/engine";
2
+ import { SoundsAudio } from "./SoundsAudio.js";
3
+ import { SoundsMelody } from "./SoundsMelody.js";
4
+ import { SoundsNote } from "./SoundsNote.js";
5
+ export class SoundsEvent {
9
6
  constructor() {
10
7
  this.event = [];
11
8
  this.notes = [];
12
9
  }
13
10
  load(data) {
14
- if ((0, engine_1.isNull)(data)) {
11
+ if (isNull(data)) {
15
12
  return;
16
13
  }
17
14
  if (data.event !== undefined) {
18
15
  this.event = data.event;
19
16
  }
20
17
  if (data.audio !== undefined) {
21
- if ((0, engine_1.isArray)(data.audio)) {
18
+ if (isArray(data.audio)) {
22
19
  this.audio = data.audio.map(s => {
23
- const tmp = new SoundsAudio_js_1.SoundsAudio();
20
+ const tmp = new SoundsAudio();
24
21
  tmp.load(s);
25
22
  return tmp;
26
23
  });
27
24
  }
28
25
  else {
29
- this.audio = new SoundsAudio_js_1.SoundsAudio();
26
+ this.audio = new SoundsAudio();
30
27
  this.audio.load(data.audio);
31
28
  }
32
29
  }
33
30
  if (data.notes !== undefined) {
34
31
  this.notes = data.notes.map(t => {
35
- const tmp = new SoundsNote_js_1.SoundsNote();
32
+ const tmp = new SoundsNote();
36
33
  tmp.load(t);
37
34
  return tmp;
38
35
  });
39
36
  }
40
37
  if (data.melodies !== undefined) {
41
38
  this.melodies = data.melodies.map(t => {
42
- const tmp = new SoundsMelody_js_1.SoundsMelody();
39
+ const tmp = new SoundsMelody();
43
40
  tmp.load(t);
44
41
  return tmp;
45
42
  });
46
43
  }
47
44
  if (data.filter) {
48
- if ((0, engine_1.isString)(data.filter)) {
49
- const filterFunc = window[data.filter];
50
- if ((0, engine_1.isFunction)(filterFunc)) {
45
+ if (isString(data.filter)) {
46
+ const filterFunc = globalThis[data.filter];
47
+ if (isFunction(filterFunc)) {
51
48
  this.filter = filterFunc;
52
49
  }
53
50
  }
@@ -57,4 +54,3 @@ class SoundsEvent {
57
54
  }
58
55
  }
59
56
  }
60
- exports.SoundsEvent = SoundsEvent;
@@ -1,15 +1,12 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsIcon = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- class SoundsIcon {
1
+ import { isNull } from "@tsparticles/engine";
2
+ export class SoundsIcon {
6
3
  constructor() {
7
4
  this.width = 24;
8
5
  this.height = 24;
9
6
  this.style = "";
10
7
  }
11
8
  load(data) {
12
- if ((0, engine_1.isNull)(data)) {
9
+ if (isNull(data)) {
13
10
  return;
14
11
  }
15
12
  if (data.path !== undefined) {
@@ -26,4 +23,3 @@ class SoundsIcon {
26
23
  }
27
24
  }
28
25
  }
29
- exports.SoundsIcon = SoundsIcon;
@@ -1,14 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsIcons = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- const SoundsIcon_js_1 = require("./SoundsIcon.js");
6
- class SoundsIcons {
1
+ import { isNull } from "@tsparticles/engine";
2
+ import { SoundsIcon } from "./SoundsIcon.js";
3
+ export class SoundsIcons {
7
4
  constructor() {
8
- this.mute = new SoundsIcon_js_1.SoundsIcon();
9
- this.unmute = new SoundsIcon_js_1.SoundsIcon();
10
- this.volumeDown = new SoundsIcon_js_1.SoundsIcon();
11
- this.volumeUp = new SoundsIcon_js_1.SoundsIcon();
5
+ this.mute = new SoundsIcon();
6
+ this.unmute = new SoundsIcon();
7
+ this.volumeDown = new SoundsIcon();
8
+ this.volumeUp = new SoundsIcon();
12
9
  this.enable = false;
13
10
  this.mute.svg = `<?xml version="1.0"?>
14
11
  <svg baseProfile="tiny" height="24px" version="1.2" viewBox="0 0 24 24" width="24px"
@@ -48,7 +45,7 @@ class SoundsIcons {
48
45
  </svg>`;
49
46
  }
50
47
  load(data) {
51
- if ((0, engine_1.isNull)(data)) {
48
+ if (isNull(data)) {
52
49
  return;
53
50
  }
54
51
  if (data.enable !== undefined) {
@@ -60,4 +57,3 @@ class SoundsIcons {
60
57
  this.volumeUp.load(data.volumeUp);
61
58
  }
62
59
  }
63
- exports.SoundsIcons = SoundsIcons;
@@ -1,16 +1,13 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsMelody = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- const SoundsNote_js_1 = require("./SoundsNote.js");
6
- class SoundsMelody {
1
+ import { isNull } from "@tsparticles/engine";
2
+ import { SoundsNote } from "./SoundsNote.js";
3
+ export class SoundsMelody {
7
4
  constructor() {
8
5
  this.loop = false;
9
6
  this.melodies = [];
10
7
  this.notes = [];
11
8
  }
12
9
  load(data) {
13
- if ((0, engine_1.isNull)(data)) {
10
+ if (isNull(data)) {
14
11
  return;
15
12
  }
16
13
  if (data.loop !== undefined) {
@@ -25,11 +22,10 @@ class SoundsMelody {
25
22
  }
26
23
  if (data.notes !== undefined) {
27
24
  this.notes = data.notes.map(s => {
28
- const tmp = new SoundsNote_js_1.SoundsNote();
25
+ const tmp = new SoundsNote();
29
26
  tmp.load(s);
30
27
  return tmp;
31
28
  });
32
29
  }
33
30
  }
34
31
  }
35
- exports.SoundsMelody = SoundsMelody;
@@ -1,14 +1,11 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsNote = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- class SoundsNote {
1
+ import { isNull } from "@tsparticles/engine";
2
+ export class SoundsNote {
6
3
  constructor() {
7
4
  this.duration = 500;
8
5
  this.value = [];
9
6
  }
10
7
  load(data) {
11
- if ((0, engine_1.isNull)(data)) {
8
+ if (isNull(data)) {
12
9
  return;
13
10
  }
14
11
  if (data.duration !== undefined) {
@@ -19,4 +16,3 @@ class SoundsNote {
19
16
  }
20
17
  }
21
18
  }
22
- exports.SoundsNote = SoundsNote;
@@ -1,8 +1,5 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SoundsVolume = void 0;
4
- const engine_1 = require("@tsparticles/engine");
5
- class SoundsVolume {
1
+ import { isNull, isObject } from "@tsparticles/engine";
2
+ export class SoundsVolume {
6
3
  constructor() {
7
4
  this.value = 100;
8
5
  this.max = 100;
@@ -10,10 +7,10 @@ class SoundsVolume {
10
7
  this.step = 10;
11
8
  }
12
9
  load(data) {
13
- if ((0, engine_1.isNull)(data)) {
10
+ if (isNull(data)) {
14
11
  return;
15
12
  }
16
- if ((0, engine_1.isObject)(data)) {
13
+ if (isObject(data)) {
17
14
  if (data.max !== undefined) {
18
15
  this.max = data.max;
19
16
  }
@@ -32,4 +29,3 @@ class SoundsVolume {
32
29
  }
33
30
  }
34
31
  }
35
- exports.SoundsVolume = SoundsVolume;
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};
@@ -1,2 +1 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
1
+ export {};