@aarsteinmedia/dotlottie-player 4.0.3 → 4.0.4

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/dist/esm/index.js CHANGED
@@ -77,12 +77,20 @@ const addExt = (ext, str)=>{
77
77
  default:
78
78
  return 'xMidYMid meet';
79
79
  }
80
- }, base64ToU8 = (str)=>strToU8(isServer() ? Buffer.from(parseBase64(str), 'base64').toString('binary') : atob(parseBase64(str)), true), createDotLottie = async ({ animations, fileName, manifest, shouldDownload = true })=>{
80
+ }, /**
81
+ * Convert Base64 encoded string to Uint8Array
82
+ * @param { string } str Base64 encoded string
83
+ * @returns { Uint8Array } UTF-8/Latin-1 binary
84
+ */ base64ToU8 = (str)=>strToU8(isServer() ? Buffer.from(parseBase64(str), 'base64').toString('binary') : atob(parseBase64(str)), true), /**
85
+ * Convert a JSON Lottie to dotLottie or combine several animations and download new dotLottie file in your browser.
86
+ */ createDotLottie = async ({ animations, fileName, manifest, shouldDownload = true })=>{
81
87
  try {
88
+ // Input validation
82
89
  if (!animations?.length || !manifest) {
83
90
  throw new Error(`Missing or malformed required parameter(s):\n ${animations?.length ? '- manifest\n' : ''} ${manifest ? '- animations\n' : ''}`);
84
91
  }
85
- const manifestCompressionLevel = 0, animationCompressionLevel = 9, name = addExt('lottie', fileName) || `${useId()}.lottie`, dotlottie = {
92
+ const manifestCompressionLevel = 0, animationCompressionLevel = 9, // Prepare the dotLottie file
93
+ name = addExt('lottie', fileName) || `${useId()}.lottie`, dotlottie = {
86
94
  'manifest.json': [
87
95
  strToU8(JSON.stringify(manifest), true),
88
96
  {
@@ -90,14 +98,19 @@ const addExt = (ext, str)=>{
90
98
  }
91
99
  ]
92
100
  };
101
+ // Add animations and assets to the dotLottie file
93
102
  for (const [i, animation] of animations.entries()){
94
103
  for (const asset of animation.assets ?? []){
95
104
  if (!asset.p || !isImage(asset) && !isAudio(asset)) {
96
105
  continue;
97
106
  }
98
- const { p: file, u: path } = asset, assetId = useId('asset'), isEncoded = file.startsWith('data:'), ext = isEncoded ? getExtFromB64(file) : getExt(file), dataURL = isEncoded ? file : await fileToBase64(path ? path.endsWith('/') && `${path}${file}` || `${path}/${file}` : file);
107
+ const { p: file, u: path } = asset, // Original asset.id caused issues with multianimations
108
+ assetId = useId('asset'), isEncoded = file.startsWith('data:'), ext = isEncoded ? getExtFromB64(file) : getExt(file), // Check if the asset is already base64-encoded. If not, get path, fetch it, and encode it
109
+ dataURL = isEncoded ? file : await fileToBase64(path ? path.endsWith('/') && `${path}${file}` || `${path}/${file}` : file);
99
110
  asset.p = `${assetId}.${ext}`;
111
+ // Asset is embedded, so path empty string
100
112
  asset.u = '';
113
+ // Asset is encoded
101
114
  asset.e = 1;
102
115
  dotlottie[`${isAudio(asset) ? 'audio' : 'images'}/${assetId}.${ext}`] = [
103
116
  base64ToU8(dataURL),
@@ -134,7 +147,11 @@ const addExt = (ext, str)=>{
134
147
  } catch (err) {
135
148
  console.error(`❌ ${handleErrors(err).message}`);
136
149
  }
137
- }, download = (data, options)=>{
150
+ }, /**
151
+ * Download file, either SVG or dotLottie.
152
+ * @param { string } data The data to be downloaded
153
+ * @param { string } name Don't include file extension in the filename
154
+ */ download = (data, options)=>{
138
155
  const blob = new Blob([
139
156
  data
140
157
  ], {
@@ -191,7 +208,11 @@ const addExt = (ext, str)=>{
191
208
  error.status = result.status;
192
209
  throw error;
193
210
  }
194
- const ext = getExt(input);
211
+ /**
212
+ * Check if file is JSON, first by parsing file name for extension,
213
+ * then – if filename has no extension – by cloning the response
214
+ * and parsing it for content.
215
+ */ const ext = getExt(input);
195
216
  if (ext === 'json' || !ext) {
196
217
  if (ext) {
197
218
  const lottie = await result.json();
@@ -244,7 +265,10 @@ const addExt = (ext, str)=>{
244
265
  });
245
266
  });
246
267
  return arrayBuffer;
247
- }, getExt = (str)=>{
268
+ }, /**
269
+ * Get extension from filename, URL or path
270
+ * @param { string } str Filename, URL or path
271
+ */ getExt = (str)=>{
248
272
  if (typeof str !== 'string' || !str || !hasExt(str)) {
249
273
  return;
250
274
  }
@@ -252,9 +276,16 @@ const addExt = (ext, str)=>{
252
276
  }, getExtFromB64 = (str)=>{
253
277
  const mime = str.split(':')[1].split(';')[0], ext = mime.split('/')[1].split('+')[0];
254
278
  return ext;
255
- }, getFilename = (src, keepExt)=>{
279
+ }, /**
280
+ * Parse URL to get filename
281
+ * @param { string } src The url string
282
+ * @param { boolean } keepExt Whether to include file extension
283
+ * @returns { string } Filename, in lowercase
284
+ */ getFilename = (src, keepExt)=>{
285
+ // Because the regex strips all special characters, we need to extract the file extension, so we can add it later if we need it
256
286
  getExt(src);
257
- return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replace(/\W+/g, '-')}${''}`;
287
+ return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replace(/\W+/g, '-')}${''}` // .toLowerCase()
288
+ ;
258
289
  }, getLottieJSON = async (resp)=>{
259
290
  const unzipped = await unzip(resp), manifest = getManifest(unzipped), data = [], toResolve = [];
260
291
  for (const { id } of manifest.animations){
@@ -346,7 +377,7 @@ const addExt = (ext, str)=>{
346
377
  await Promise.all(toResolve);
347
378
  }, unzip = async (resp)=>{
348
379
  const u8 = new Uint8Array(await resp.arrayBuffer()), unzipped = await new Promise((resolve, reject)=>{
349
- unzip$1(u8, (err, file)=>{
380
+ unzip$1(u8, /* { filter }, */ (err, file)=>{
350
381
  if (err) {
351
382
  reject(err);
352
383
  }
@@ -359,15 +390,19 @@ const addExt = (ext, str)=>{
359
390
  return `${prefix ?? `:${s4()}`}_${s4()}`;
360
391
  };
361
392
 
362
- function renderPlayer() {
363
- this.template.innerHTML = `<div class="animation-container main" data-controls="${this.controls ?? false}" lang="${this.description ? document?.documentElement?.lang : 'en'}" role="img" aria-label="${this.description ?? 'Lottie animation'}" data-loaded="${this._playerState.loaded}"><figure class="animation" style="background:${this.background}">${this.playerState === PlayerState.Error ? `<div class="error"><svg preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1920" height="1080" viewBox="0 0 1920 1080"><path fill="#fff" d="M0 0h1920v1080H0z"/><path fill="#3a6d8b" d="M1190.2 531 1007 212.4c-22-38.2-77.2-38-98.8.5L729.5 531.3c-21.3 37.9 6.1 84.6 49.5 84.6l361.9.3c43.7 0 71.1-47.3 49.3-85.2zM937.3 288.7c.2-7.5 3.3-23.9 23.2-23.9 16.3 0 23 16.1 23 23.5 0 55.3-10.7 197.2-12.2 214.5-.1 1-.9 1.7-1.9 1.7h-18.3c-1 0-1.8-.7-1.9-1.7-1.4-17.5-13.4-162.9-11.9-214.1zm24.2 283.8c-13.1 0-23.7-10.6-23.7-23.7s10.6-23.7 23.7-23.7 23.7 10.6 23.7 23.7-10.6 23.7-23.7 23.7zM722.1 644h112.6v34.4h-70.4V698h58.8v31.7h-58.8v22.6h72.4v36.2H722.1V644zm162 57.1h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6zm78.9 0h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5H963v15.6zm39.5 36.2c0-31.3 22.2-54.8 56.6-54.8 34.4 0 56.2 23.5 56.2 54.8s-21.8 54.6-56.2 54.6c-34.4-.1-56.6-23.3-56.6-54.6zm74 0c0-17.4-6.1-29.1-17.8-29.1-11.7 0-17.4 11.7-17.4 29.1 0 17.4 5.7 29.1 17.4 29.1s17.8-11.8 17.8-29.1zm83.1-36.2h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6z"/><path fill="none" d="M718.9 807.7h645v285.4h-645z"/><text fill="#3a6d8b" style="text-align:center;position:absolute;left:100%;font-size:47px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'.SFNSText-Regular',sans-serif" x="50%" y="848.017" text-anchor="middle">${this._errorMessage}</text></svg></div>` : ''}</figure><slot name="controls"></slot></div>`;
393
+ /**
394
+ * Render Player
395
+ */ function renderPlayer() {
396
+ this.template.innerHTML = /* HTML */ `<div class="animation-container main" data-controls="${this.controls ?? false}" lang="${this.description ? document?.documentElement?.lang : 'en'}" role="img" aria-label="${this.description ?? 'Lottie animation'}" data-loaded="${this._playerState.loaded}"><figure class="animation" style="background:${this.background}">${this.playerState === PlayerState.Error ? /* HTML */ `<div class="error"><svg preserveAspectRatio="xMidYMid slice" xmlns="http://www.w3.org/2000/svg" xml:space="preserve" width="1920" height="1080" viewBox="0 0 1920 1080"><path fill="#fff" d="M0 0h1920v1080H0z"/><path fill="#3a6d8b" d="M1190.2 531 1007 212.4c-22-38.2-77.2-38-98.8.5L729.5 531.3c-21.3 37.9 6.1 84.6 49.5 84.6l361.9.3c43.7 0 71.1-47.3 49.3-85.2zM937.3 288.7c.2-7.5 3.3-23.9 23.2-23.9 16.3 0 23 16.1 23 23.5 0 55.3-10.7 197.2-12.2 214.5-.1 1-.9 1.7-1.9 1.7h-18.3c-1 0-1.8-.7-1.9-1.7-1.4-17.5-13.4-162.9-11.9-214.1zm24.2 283.8c-13.1 0-23.7-10.6-23.7-23.7s10.6-23.7 23.7-23.7 23.7 10.6 23.7 23.7-10.6 23.7-23.7 23.7zM722.1 644h112.6v34.4h-70.4V698h58.8v31.7h-58.8v22.6h72.4v36.2H722.1V644zm162 57.1h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6zm78.9 0h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5H963v15.6zm39.5 36.2c0-31.3 22.2-54.8 56.6-54.8 34.4 0 56.2 23.5 56.2 54.8s-21.8 54.6-56.2 54.6c-34.4-.1-56.6-23.3-56.6-54.6zm74 0c0-17.4-6.1-29.1-17.8-29.1-11.7 0-17.4 11.7-17.4 29.1 0 17.4 5.7 29.1 17.4 29.1s17.8-11.8 17.8-29.1zm83.1-36.2h.6c8.3-12.9 18.2-17.8 31.3-17.8 3 0 5.1.4 6.3 1v32.6h-.8c-22.4-3.8-35.6 6.3-35.6 29.5v42.3h-38.2V685.5h36.4v15.6z"/><path fill="none" d="M718.9 807.7h645v285.4h-645z"/><text fill="#3a6d8b" style="text-align:center;position:absolute;left:100%;font-size:47px;font-family:system-ui,-apple-system,BlinkMacSystemFont,'.SFNSText-Regular',sans-serif" x="50%" y="848.017" text-anchor="middle">${this._errorMessage}</text></svg></div>` : ''}</figure><slot name="controls"></slot></div>`;
364
397
  this.shadow.adoptedStyleSheets = [
365
398
  DotLottiePlayer.styles
366
399
  ];
367
400
  this.shadow.appendChild(this.template.content.cloneNode(true));
368
401
  }
369
402
 
370
- function renderControls() {
403
+ /**
404
+ * Render Controls
405
+ */ function renderControls() {
371
406
  const slot = this.shadow.querySelector('slot[name=controls]');
372
407
  if (!slot) {
373
408
  return;
@@ -376,7 +411,7 @@ function renderControls() {
376
411
  slot.innerHTML = '';
377
412
  return;
378
413
  }
379
- slot.innerHTML = `<div class="lottie-controls toolbar ${this.playerState === PlayerState.Error ? 'has-error' : ''}" aria-label="Lottie Animation controls"><button class="togglePlay" data-active="false" aria-label="Toggle Play/Pause"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg></button> <button class="stop" data-active="true" aria-label="Stop"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M6 6h12v12H6V6z"/></svg></button> <button class="prev" aria-label="Previous animation" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.9 18.2 8.1 12l9.8-6.2v12.4zm-10.3 0H6.1V5.8h1.5v12.4z"/></svg></button> <button class="next" aria-label="Next animation" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="m6.1 5.8 9.8 6.2-9.8 6.2V5.8zM16.4 5.8h1.5v12.4h-1.5z"/></svg></button><form class="progress-container${this.simple ? ' simple' : ''}"><input class="seeker" type="range" min="0" max="100" step="1" value="${this._seeker.toString()}" aria-valuemin="0" aria-valuemax="100" role="slider" aria-valuenow="${this._seeker.toString()}" tabindex="0" aria-label="Slider for search"><progress max="100" value="${this._seeker}"></progress></form>${this.simple ? '' : `<button class="toggleLoop" data-active="${this.loop}" tabindex="0" aria-label="Toggle loop"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"/></svg></button> <button class="toggleBoomerang" data-active="${this.mode === PlayMode.Bounce}" aria-label="Toggle boomerang" tabindex="0"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="m11.8 13.2-.3.3c-.5.5-1.1 1.1-1.7 1.5-.5.4-1 .6-1.5.8-.5.2-1.1.3-1.6.3s-1-.1-1.5-.3c-.6-.2-1-.5-1.4-1-.5-.6-.8-1.2-.9-1.9-.2-.9-.1-1.8.3-2.6.3-.7.8-1.2 1.3-1.6.3-.2.6-.4 1-.5.2-.2.5-.2.8-.3.3 0 .7-.1 1 0 .3 0 .6.1.9.2.9.3 1.7.9 2.4 1.5.4.4.8.7 1.1 1.1l.1.1.4-.4c.6-.6 1.2-1.2 1.9-1.6.5-.3 1-.6 1.5-.7.4-.1.7-.2 1-.2h.9c1 .1 1.9.5 2.6 1.4.4.5.7 1.1.8 1.8.2.9.1 1.7-.2 2.5-.4.9-1 1.5-1.8 2-.4.2-.7.4-1.1.4-.4.1-.8.1-1.2.1-.5 0-.9-.1-1.3-.3-.8-.3-1.5-.9-2.1-1.5-.4-.4-.8-.7-1.1-1.1h-.3zm-1.1-1.1c-.1-.1-.1-.1 0 0-.3-.3-.6-.6-.8-.9-.5-.5-1-.9-1.6-1.2-.4-.3-.8-.4-1.3-.4-.4 0-.8 0-1.1.2-.5.2-.9.6-1.1 1-.2.3-.3.7-.3 1.1 0 .3 0 .6.1.9.1.5.4.9.8 1.2.5.4 1.1.5 1.7.5.5 0 1-.2 1.5-.5.6-.4 1.1-.8 1.6-1.3.1-.3.3-.5.5-.6zM13 12c.5.5 1 1 1.5 1.4.5.5 1.1.9 1.9 1 .4.1.8 0 1.2-.1.3-.1.6-.3.9-.5.4-.4.7-.9.8-1.4.1-.5 0-.9-.1-1.4-.3-.8-.8-1.2-1.7-1.4-.4-.1-.8-.1-1.2 0-.5.1-1 .4-1.4.7-.5.4-1 .8-1.4 1.2-.2.2-.4.3-.5.5z"/></svg></button> <button class="toggleSettings" aria-label="Settings" aria-haspopup="true" aria-expanded="${!!this._isSettingsOpen}" aria-controls="${this._identifier}-settings"><svg width="24" height="24" aria-hidden="true" focusable="false"><circle cx="12" cy="5.4" r="2.5"/><circle cx="12" cy="12" r="2.5"/><circle cx="12" cy="18.6" r="2.5"/></svg></button><div id="${this._identifier}-settings" class="popover" hidden><button class="convert" aria-label="Convert JSON animation to dotLottie format" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"/></svg> Convert to dotLottie</button> <button class="snapshot" aria-label="Download still image"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M16.8 10.8 12 15.6l-4.8-4.8h3V3.6h3.6v7.2h3zM12 15.6H3v4.8h18v-4.8h-9zm7.8 2.4h-2.4v-1.2h2.4V18z"/></svg> Download still image</button></div>`}</div>`;
414
+ slot.innerHTML = /* HTML */ `<div class="lottie-controls toolbar ${this.playerState === PlayerState.Error ? 'has-error' : ''}" aria-label="Lottie Animation controls"><button class="togglePlay" data-active="false" aria-label="Toggle Play/Pause"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg></button> <button class="stop" data-active="true" aria-label="Stop"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M6 6h12v12H6V6z"/></svg></button> <button class="prev" aria-label="Previous animation" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.9 18.2 8.1 12l9.8-6.2v12.4zm-10.3 0H6.1V5.8h1.5v12.4z"/></svg></button> <button class="next" aria-label="Next animation" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="m6.1 5.8 9.8 6.2-9.8 6.2V5.8zM16.4 5.8h1.5v12.4h-1.5z"/></svg></button><form class="progress-container${this.simple ? ' simple' : ''}"><input class="seeker" type="range" min="0" max="100" step="1" value="${this._seeker.toString()}" aria-valuemin="0" aria-valuemax="100" role="slider" aria-valuenow="${this._seeker.toString()}" tabindex="0" aria-label="Slider for search"><progress max="100" value="${this._seeker}"></progress></form>${this.simple ? '' : /* HTML */ `<button class="toggleLoop" data-active="${this.loop}" tabindex="0" aria-label="Toggle loop"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"/></svg></button> <button class="toggleBoomerang" data-active="${this.mode === PlayMode.Bounce}" aria-label="Toggle boomerang" tabindex="0"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="m11.8 13.2-.3.3c-.5.5-1.1 1.1-1.7 1.5-.5.4-1 .6-1.5.8-.5.2-1.1.3-1.6.3s-1-.1-1.5-.3c-.6-.2-1-.5-1.4-1-.5-.6-.8-1.2-.9-1.9-.2-.9-.1-1.8.3-2.6.3-.7.8-1.2 1.3-1.6.3-.2.6-.4 1-.5.2-.2.5-.2.8-.3.3 0 .7-.1 1 0 .3 0 .6.1.9.2.9.3 1.7.9 2.4 1.5.4.4.8.7 1.1 1.1l.1.1.4-.4c.6-.6 1.2-1.2 1.9-1.6.5-.3 1-.6 1.5-.7.4-.1.7-.2 1-.2h.9c1 .1 1.9.5 2.6 1.4.4.5.7 1.1.8 1.8.2.9.1 1.7-.2 2.5-.4.9-1 1.5-1.8 2-.4.2-.7.4-1.1.4-.4.1-.8.1-1.2.1-.5 0-.9-.1-1.3-.3-.8-.3-1.5-.9-2.1-1.5-.4-.4-.8-.7-1.1-1.1h-.3zm-1.1-1.1c-.1-.1-.1-.1 0 0-.3-.3-.6-.6-.8-.9-.5-.5-1-.9-1.6-1.2-.4-.3-.8-.4-1.3-.4-.4 0-.8 0-1.1.2-.5.2-.9.6-1.1 1-.2.3-.3.7-.3 1.1 0 .3 0 .6.1.9.1.5.4.9.8 1.2.5.4 1.1.5 1.7.5.5 0 1-.2 1.5-.5.6-.4 1.1-.8 1.6-1.3.1-.3.3-.5.5-.6zM13 12c.5.5 1 1 1.5 1.4.5.5 1.1.9 1.9 1 .4.1.8 0 1.2-.1.3-.1.6-.3.9-.5.4-.4.7-.9.8-1.4.1-.5 0-.9-.1-1.4-.3-.8-.8-1.2-1.7-1.4-.4-.1-.8-.1-1.2 0-.5.1-1 .4-1.4.7-.5.4-1 .8-1.4 1.2-.2.2-.4.3-.5.5z"/></svg></button> <button class="toggleSettings" aria-label="Settings" aria-haspopup="true" aria-expanded="${!!this._isSettingsOpen}" aria-controls="${this._identifier}-settings"><svg width="24" height="24" aria-hidden="true" focusable="false"><circle cx="12" cy="5.4" r="2.5"/><circle cx="12" cy="12" r="2.5"/><circle cx="12" cy="18.6" r="2.5"/></svg></button><div id="${this._identifier}-settings" class="popover" hidden><button class="convert" aria-label="Convert JSON animation to dotLottie format" hidden><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M17.016 17.016v-4.031h1.969v6h-12v3l-3.984-3.984 3.984-3.984v3h10.031zM6.984 6.984v4.031H5.015v-6h12v-3l3.984 3.984-3.984 3.984v-3H6.984z"/></svg> Convert to dotLottie</button> <button class="snapshot" aria-label="Download still image"><svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M16.8 10.8 12 15.6l-4.8-4.8h3V3.6h3.6v7.2h3zM12 15.6H3v4.8h18v-4.8h-9zm7.8 2.4h-2.4v-1.2h2.4V18z"/></svg> Download still image</button></div>`}</div>`;
380
415
  const togglePlay = this.shadow.querySelector('.togglePlay');
381
416
  if (togglePlay instanceof HTMLButtonElement) {
382
417
  togglePlay.onclick = this.togglePlay;
@@ -423,8 +458,14 @@ function renderControls() {
423
458
  }
424
459
  }
425
460
 
426
- const UPDATE_ON_CONNECTED = Symbol('UPDATE_ON_CONNECTED');
461
+ /**
462
+ * Credit to:
463
+ * @author Leonardo Favre <https://github.com/leofavre/observed-properties>
464
+ * @description Enhanced HTML element with reactive state handlers
465
+ */ /* eslint-disable @typescript-eslint/ban-ts-comment */ const UPDATE_ON_CONNECTED = Symbol('UPDATE_ON_CONNECTED');
427
466
  if (isServer()) {
467
+ // Mock HTMLElement for server-side rendering
468
+ // @ts-ignore
428
469
  global.HTMLElement = class EmptyHTMLElement {
429
470
  };
430
471
  }
@@ -445,6 +486,7 @@ let EnhancedElement = class EnhancedElement extends HTMLElement {
445
486
  }
446
487
  constructor(){
447
488
  super();
489
+ // @ts-ignore
448
490
  const { observedProperties = [] } = this.constructor;
449
491
  if (UPDATE_ON_CONNECTED in this) {
450
492
  this[UPDATE_ON_CONNECTED] = [];
@@ -452,6 +494,7 @@ let EnhancedElement = class EnhancedElement extends HTMLElement {
452
494
  if ('propertyChangedCallback' in this && typeof this.propertyChangedCallback === 'function') {
453
495
  for (const propName of observedProperties){
454
496
  const initialValue = this[propName], CACHED_VALUE = Symbol(propName);
497
+ // @ts-ignore
455
498
  this[CACHED_VALUE] = initialValue;
456
499
  Object.defineProperty(this, propName, {
457
500
  get () {
@@ -473,34 +516,46 @@ let EnhancedElement = class EnhancedElement extends HTMLElement {
473
516
  }
474
517
  };
475
518
 
476
- var $schema="https://json.schemastore.org/package";var name="@aarsteinmedia/dotlottie-player";var version="4.0.3";var description="Web Component for playing Lottie animations in your web app. Previously @johanaarstein/dotlottie-player";var exports={".":{"import":"./dist/esm/index.js",node:"./dist/esm/index.js",require:"./dist/cjs/index.js",types:"./dist/index.d.ts"}};var main="./dist/esm/index.js";var unpkg="./dist/index.js";var module="./dist/esm/index.js";var types="./dist/index.d.ts";var type="module";var homepage="https://www.aarstein.media/en/dotlottie-player";var repository={url:"git+https://github.com/aarsteinmedia/dotlottie-player.git",type:"git"};var bugs="https://github.com/aarsteinmedia/dotlottie-player/issues";var author={name:"Johan Martin Aarstein",email:"johan@aarstein.media",url:"https://www.aarstein.media",organization:"Aarstein Media"};var contributors=[{name:"Anthony Colpron",email:"anthonycolpron@gmail.com",url:"https://github.com/anthony-colpron"}];var license="GPL-2.0-or-later";var scripts={test:"wtr",prebuild:"rimraf ./dist",build:"rollup -c","prebuild:types":"rimraf ./types","build:types":"tsc -p ./tsconfig.prod.json && tsc-alias","build:cem":"npx cem analyze --config cem.config.mjs",prod:"pnpm build:types && pnpm build && pnpm build:cem",dev:"rollup -c -w --environment NODE_ENV:development","lint:js":"eslint","lint:js:fix":"eslint --fix","lint:css":"npx stylelint **/*.scss","lint:css:fix":"npx stylelint **/*.scss --fix","lint:pkg":"npmPkgJsonLint .","lint:pkg:fix":"npmPkgJsonLint . --fix"};var dependencies={fflate:"^0.8.2","lottie-web":"^5.12.2"};var peerDependencies={"@types/react":">= 16.0.0"};var devDependencies={"@custom-elements-manifest/analyzer":"^0.10.3","@eslint/compat":"^1.2.2","@eslint/eslintrc":"^3.1.0","@eslint/js":"^9.13.0","@esm-bundle/chai":"4.3.4-fix.0","@open-wc/testing":"^4.0.0","@rollup/plugin-commonjs":"^28.0.1","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.3.0","@rollup/plugin-typescript":"^11.1.6","@swc/core":"^1.7.40","@types/mocha":"^10.0.9","@types/node":"^22.8.4","@typescript-eslint/eslint-plugin":"^8.12.2","@typescript-eslint/parser":"^8.12.2","@web/dev-server-esbuild":"^1.0.2","@web/dev-server-import-maps":"^0.2.1","@web/dev-server-rollup":"^0.6.4","@web/test-runner":"^0.19.0","@web/test-runner-playwright":"^0.11.0",autoprefixer:"^10.4.20",esbuild:"^0.24.0","esbuild-sass-plugin":"^3.3.1",eslint:"^9.13.0","eslint-config-prettier":"^9.1.0","eslint-import-resolver-typescript":"^3.6.3","eslint-plugin-import":"^2.31.0","eslint-plugin-jsdoc":"^48.11.0","eslint-plugin-perfectionist":"^3.9.1","eslint-plugin-prettier":"^5.2.1",globals:"^15.11.0","npm-package-json-lint":"^8.0.0","npm-package-json-lint-config-default":"^7.0.1","postcss-flexbugs-fixes":"^5.0.2",prettier:"^3.3.3",rimraf:"^6.0.1",rollup:"^4.24.3","rollup-plugin-dts":"^6.1.1","rollup-plugin-html-literals":"^1.1.8","rollup-plugin-livereload":"^2.0.5","rollup-plugin-postcss":"^4.0.2","rollup-plugin-serve":"^1.1.1","rollup-plugin-summary":"^2.0.1","rollup-plugin-swc3":"^0.12.1","rollup-plugin-typescript-paths":"^1.5.0",sass:"^1.80.5",stylelint:"^16.10.0","stylelint-config-standard-scss":"^13.1.0","tsc-alias":"^1.8.10",tslib:"^2.8.0",typescript:"^5.6.3"};var browserslist={production:[">0.3%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]};var customElements$1="custom-elements.json";var files=["custom-elements.json","dist","README.md"];var keywords=["lottie","dotlottie","animation","web component","svg","vector","player"];var publishConfig={access:"public"};var engines={node:">= 8.17.0"};var funding={type:"paypal",url:"https://www.paypal.com/donate/?hosted_button_id=E7C7DMN8KSQ6A"};var pkg = {$schema:$schema,name:name,version:version,description:description,exports:exports,main:main,unpkg:unpkg,module:module,types:types,type:type,homepage:homepage,repository:repository,bugs:bugs,author:author,contributors:contributors,license:license,scripts:scripts,dependencies:dependencies,peerDependencies:peerDependencies,devDependencies:devDependencies,browserslist:browserslist,customElements:customElements$1,files:files,keywords:keywords,publishConfig:publishConfig,engines:engines,funding:funding};
519
+ var $schema="https://json.schemastore.org/package";var name="@aarsteinmedia/dotlottie-player";var version="4.0.4";var description="Web Component for playing Lottie animations in your web app. Previously @johanaarstein/dotlottie-player";var exports={".":{"import":"./dist/esm/index.js",node:"./dist/esm/index.js",require:"./dist/cjs/index.js",types:"./dist/index.d.ts"}};var main="./dist/esm/index.js";var unpkg="./dist/index.js";var module="./dist/esm/index.js";var types="./dist/index.d.ts";var type="module";var homepage="https://www.aarstein.media/en/dotlottie-player";var repository={url:"git+https://github.com/aarsteinmedia/dotlottie-player.git",type:"git"};var bugs="https://github.com/aarsteinmedia/dotlottie-player/issues";var author={name:"Johan Martin Aarstein",email:"johan@aarstein.media",url:"https://www.aarstein.media",organization:"Aarstein Media"};var contributors=[{name:"Anthony Colpron",email:"anthonycolpron@gmail.com",url:"https://github.com/anthony-colpron"}];var license="GPL-2.0-or-later";var scripts={test:"wtr",prebuild:"rimraf ./dist",build:"rollup -c","prebuild:types":"rimraf ./types","build:types":"tsc -p ./tsconfig.prod.json && tsc-alias","build:cem":"npx cem analyze --config cem.config.mjs",prod:"pnpm build:types && pnpm build && pnpm build:cem",dev:"rollup -c -w --environment NODE_ENV:development","lint:js":"eslint","lint:js:fix":"eslint --fix","lint:css":"npx stylelint **/*.scss","lint:css:fix":"npx stylelint **/*.scss --fix","lint:pkg":"npmPkgJsonLint .","lint:pkg:fix":"npmPkgJsonLint . --fix"};var dependencies={fflate:"^0.8.2","lottie-web":"^5.12.2"};var peerDependencies={"@types/react":">= 16.0.0"};var devDependencies={"@custom-elements-manifest/analyzer":"^0.10.3","@eslint/compat":"^1.2.2","@eslint/eslintrc":"^3.1.0","@eslint/js":"^9.13.0","@esm-bundle/chai":"4.3.4-fix.0","@open-wc/testing":"^4.0.0","@rollup/plugin-commonjs":"^28.0.1","@rollup/plugin-json":"^6.1.0","@rollup/plugin-node-resolve":"^15.3.0","@rollup/plugin-typescript":"^11.1.6","@swc/core":"^1.7.42","@types/mocha":"^10.0.9","@types/node":"^22.8.5","@typescript-eslint/eslint-plugin":"^8.12.2","@typescript-eslint/parser":"^8.12.2","@web/dev-server-esbuild":"^1.0.2","@web/dev-server-import-maps":"^0.2.1","@web/dev-server-rollup":"^0.6.4","@web/test-runner":"^0.19.0","@web/test-runner-playwright":"^0.11.0",autoprefixer:"^10.4.20",esbuild:"^0.24.0","esbuild-sass-plugin":"^3.3.1",eslint:"^9.13.0","eslint-config-prettier":"^9.1.0","eslint-import-resolver-typescript":"^3.6.3","eslint-plugin-import":"^2.31.0","eslint-plugin-jsdoc":"^48.11.0","eslint-plugin-perfectionist":"^3.9.1","eslint-plugin-prettier":"^5.2.1",globals:"^15.11.0","npm-package-json-lint":"^8.0.0","npm-package-json-lint-config-default":"^7.0.1","postcss-flexbugs-fixes":"^5.0.2",prettier:"^3.3.3",rimraf:"^6.0.1",rollup:"^4.24.3","rollup-plugin-dts":"^6.1.1","rollup-plugin-html-literals":"^1.1.8","rollup-plugin-livereload":"^2.0.5","rollup-plugin-postcss":"^4.0.2","rollup-plugin-serve":"^1.1.1","rollup-plugin-summary":"^2.0.1","rollup-plugin-swc3":"^0.12.1","rollup-plugin-typescript-paths":"^1.5.0",sass:"^1.80.5",stylelint:"^16.10.0","stylelint-config-standard-scss":"^13.1.0","tsc-alias":"^1.8.10",tslib:"^2.8.0",typescript:"^5.6.3"};var browserslist={production:[">0.3%","not dead","not op_mini all"],development:["last 1 chrome version","last 1 firefox version","last 1 safari version"]};var customElements$1="custom-elements.json";var files=["CHANGELOG.md","custom-elements.json","dist","README.md"];var keywords=["lottie","dotlottie","animation","web component","svg","vector","player"];var publishConfig={access:"public"};var engines={node:">= 8.17.0"};var funding={type:"paypal",url:"https://www.paypal.com/donate/?hosted_button_id=E7C7DMN8KSQ6A"};var pkg = {$schema:$schema,name:name,version:version,description:description,exports:exports,main:main,unpkg:unpkg,module:module,types:types,type:type,homepage:homepage,repository:repository,bugs:bugs,author:author,contributors:contributors,license:license,scripts:scripts,dependencies:dependencies,peerDependencies:peerDependencies,devDependencies:devDependencies,browserslist:browserslist,customElements:customElements$1,files:files,keywords:keywords,publishConfig:publishConfig,engines:engines,funding:funding};
477
520
 
478
521
  var css_248z = "* {\n box-sizing: border-box;\n}\n\n:host {\n --lottie-player-toolbar-height: 35px;\n --lottie-player-toolbar-background-color: #FFF;\n --lottie-player-toolbar-icon-color: #000;\n --lottie-player-toolbar-icon-hover-color: #000;\n --lottie-player-toolbar-icon-active-color: #4285f4;\n --lottie-player-seeker-track-color: rgb(0 0 0 / 20%);\n --lottie-player-seeker-thumb-color: #4285f4;\n --lottie-player-seeker-display: block;\n display: block;\n width: 100%;\n height: 100%;\n}\n:host .main {\n display: flex;\n flex-direction: column;\n height: 100%;\n width: 100%;\n margin: 0;\n padding: 0;\n}\n:host .animation {\n width: 100%;\n height: 100%;\n display: flex;\n margin: 0;\n padding: 0;\n}\n:host [data-controls=true] .animation {\n height: calc(100% - 35px);\n}\n:host .animation-container {\n position: relative;\n}\n:host .popover {\n position: absolute;\n right: 5px;\n bottom: 40px;\n background-color: var(--lottie-player-toolbar-background-color);\n border-radius: 5px;\n padding: 10px 15px;\n border: solid 2px var(--lottie-player-toolbar-icon-color);\n animation: fade-in 0.2s ease-in-out;\n}\n:host .popover::before {\n content: \"\";\n right: 10px;\n border: 7px solid transparent;\n margin-right: -7px;\n height: 0;\n width: 0;\n position: absolute;\n pointer-events: none;\n top: 100%;\n border-top-color: var(--lottie-player-toolbar-icon-color);\n}\n:host .error {\n display: flex;\n margin: auto;\n justify-content: center;\n height: 100%;\n align-items: center;\n}\n:host .error svg {\n width: 100%;\n height: auto;\n}\n:host .toolbar {\n display: flex;\n place-items: center center;\n background: var(--lottie-player-toolbar-background-color);\n margin: 0;\n height: 35px;\n padding: 5px;\n border-radius: 5px;\n gap: 5px;\n}\n:host .toolbar.has-error {\n pointer-events: none;\n opacity: 0.5;\n}\n:host .toolbar button {\n cursor: pointer;\n fill: var(--lottie-player-toolbar-icon-color);\n color: var(--lottie-player-toolbar-icon-color);\n background: none;\n border: 0;\n padding: 0;\n outline: 0;\n height: 100%;\n margin: 0;\n align-items: center;\n gap: 5px;\n opacity: 0.9;\n}\n:host .toolbar button:not([hidden]) {\n display: flex;\n}\n:host .toolbar button:hover {\n opacity: 1;\n}\n:host .toolbar button[data-active=true] {\n opacity: 1;\n fill: var(--lottie-player-toolbar-icon-active-color);\n}\n:host .toolbar button:disabled {\n opacity: 0.5;\n}\n:host .toolbar button:focus {\n outline: 0;\n}\n:host .toolbar button svg {\n pointer-events: none;\n}\n:host .toolbar button svg > * {\n fill: inherit;\n}\n:host .toolbar button.disabled svg {\n display: none;\n}\n:host .progress-container {\n position: relative;\n width: 100%;\n}\n:host .progress-container.simple {\n margin-right: 12px;\n}\n:host .seeker {\n appearance: none;\n outline: none;\n width: 100%;\n height: 20px;\n border-radius: 3px;\n border: 0;\n cursor: pointer;\n background-color: transparent;\n /* background-color: var(--lottie-player-seeker-track-color); */\n display: var(--lottie-player-seeker-display);\n color: var(--lottie-player-seeker-thumb-color);\n margin: 0;\n padding: 7.5px 0;\n position: relative;\n z-index: 1;\n}\n:host .seeker::-webkit-slider-runnable-track, :host .seeker::-webkit-slider-thumb {\n appearance: none;\n outline: none;\n}\n:host .seeker::-webkit-slider-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n border: 0;\n background-color: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -webkit-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n}\n:host .seeker:hover::-webkit-slider-thumb, :host .seeker:focus::-webkit-slider-thumb {\n transform: scale(1);\n}\n:host .seeker::-moz-range-progress {\n background-color: var(--lottie-player-seeker-thumb-color);\n height: 5px;\n border-radius: 3px;\n}\n:host .seeker::-moz-range-thumb {\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background-color: var(--lottie-player-seeker-thumb-color);\n border: 0;\n cursor: pointer;\n -moz-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n}\n:host .seeker:hover::-moz-range-thumb, :host .seeker:focus::-moz-range-thumb {\n transform: scale(1);\n}\n:host .seeker::-ms-track {\n width: 100%;\n height: 5px;\n cursor: pointer;\n background: transparent;\n border-color: transparent;\n color: transparent;\n}\n:host .seeker::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n border-radius: 3px;\n}\n:host .seeker::-ms-fill-lower {\n background-color: var(--lottie-player-seeker-thumb-color);\n border-radius: 3px;\n}\n:host .seeker::-ms-thumb {\n border: 0;\n height: 15px;\n width: 15px;\n border-radius: 50%;\n background: var(--lottie-player-seeker-thumb-color);\n cursor: pointer;\n -ms-transition: transform 0.2s ease-in-out;\n transition: transform 0.2s ease-in-out;\n transform: scale(0);\n}\n:host .seeker:hover::-ms-thumb {\n transform: scale(1);\n}\n:host .seeker:focus::-ms-thumb {\n transform: scale(1);\n}\n:host .seeker:focus::-ms-fill-lower, :host .seeker:focus::-ms-fill-upper {\n background: var(--lottie-player-seeker-track-color);\n}\n:host progress {\n appearance: none;\n outline: none;\n position: absolute;\n width: 100%;\n height: 5px;\n border-radius: 3px;\n border: 0;\n top: 0;\n left: 0;\n margin: 7.5px 0;\n background-color: var(--lottie-player-seeker-track-color);\n pointer-events: none;\n}\n:host ::-moz-progress-bar {\n background-color: var(--lottie-player-seeker-thumb-color);\n}\n:host ::-webkit-progress-inner-element {\n border-radius: 3px;\n overflow: hidden;\n}\n:host ::-webkit-slider-runnable-track {\n background-color: transparent;\n}\n:host ::-webkit-progress-value {\n background-color: var(--lottie-player-seeker-thumb-color);\n}\n\n@keyframes fade-in {\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n}\n@media (prefers-color-scheme: dark) {\n :host {\n --lottie-player-toolbar-background-color: #000;\n --lottie-player-toolbar-icon-color: #FFF;\n --lottie-player-toolbar-icon-hover-color: #FFF;\n --lottie-player-seeker-track-color: rgb(255 255 255 / 60%);\n }\n}";
479
522
 
480
523
  let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
481
- async connectedCallback() {
524
+ /**
525
+ * Initialize everything on component first render
526
+ */ async connectedCallback() {
482
527
  super.connectedCallback();
483
528
  this._render();
484
529
  this._container = this.shadow.querySelector('.animation');
485
530
  this._renderControls();
531
+ // Add listener for Visibility API's change event.
486
532
  if (typeof document.hidden !== 'undefined') {
487
533
  document.addEventListener('visibilitychange', this._onVisibilityChange);
488
534
  }
535
+ // Add intersection observer for detecting component being out-of-view.
489
536
  this._addIntersectionObserver();
537
+ // Setup lottie player
490
538
  await this.load(this.src);
491
539
  this.dispatchEvent(new CustomEvent(PlayerEvents.Rendered));
492
540
  }
493
- disconnectedCallback() {
541
+ /**
542
+ * Cleanup on component destroy
543
+ */ disconnectedCallback() {
544
+ // Remove intersection observer for detecting component being out-of-view
494
545
  if (this._intersectionObserver) {
495
546
  this._intersectionObserver.disconnect();
496
547
  this._intersectionObserver = undefined;
497
548
  }
549
+ // Destroy the animation instance
498
550
  if (this._lottieInstance) {
499
551
  this._lottieInstance.destroy();
500
552
  }
553
+ // Remove the attached Visibility API's change event listener
501
554
  document.removeEventListener('visibilitychange', this._onVisibilityChange);
502
555
  }
503
- static get observedAttributes() {
556
+ /**
557
+ * Attributes to observe
558
+ */ static get observedAttributes() {
504
559
  return [
505
560
  'animateOnScroll',
506
561
  'autoplay',
@@ -514,7 +569,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
514
569
  'subframe'
515
570
  ];
516
571
  }
517
- async attributeChangedCallback(name, _oldValue, value) {
572
+ /**
573
+ * Runs when the value of an attribute is changed on the component
574
+ */ async attributeChangedCallback(name, _oldValue, value) {
518
575
  if (!this._lottieInstance) {
519
576
  return;
520
577
  }
@@ -593,6 +650,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
593
650
  '_animations'
594
651
  ];
595
652
  }
653
+ // name: string, oldValue: string, newValue: string
596
654
  propertyChangedCallback(name, _oldValue, value) {
597
655
  if (!this.shadow) {
598
656
  return;
@@ -605,9 +663,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
605
663
  togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
606
664
  stop.dataset.active = (value === PlayerState.Stopped).toString();
607
665
  if (value === PlayerState.Playing) {
608
- togglePlay.innerHTML = `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M14.016 5.016H18v13.969h-3.984V5.016zM6 18.984V5.015h3.984v13.969H6z"/></svg>`;
666
+ togglePlay.innerHTML = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M14.016 5.016H18v13.969h-3.984V5.016zM6 18.984V5.015h3.984v13.969H6z"/></svg>`;
609
667
  } else {
610
- togglePlay.innerHTML = `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg>`;
668
+ togglePlay.innerHTML = /* HTML */ `<svg width="24" height="24" aria-hidden="true" focusable="false"><path d="M8.016 5.016L18.985 12 8.016 18.984V5.015z"/></svg>`;
611
669
  }
612
670
  }
613
671
  if (name === '_seeker' && typeof value === 'number') {
@@ -637,7 +695,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
637
695
  convert.hidden = this._isDotLottie;
638
696
  }
639
697
  }
640
- set animateOnScroll(value) {
698
+ /**
699
+ * Whether to trigger next frame with scroll
700
+ */ set animateOnScroll(value) {
641
701
  this.setAttribute('animateOnScroll', (!!value).toString());
642
702
  }
643
703
  get animateOnScroll() {
@@ -647,7 +707,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
647
707
  }
648
708
  return false;
649
709
  }
650
- set autoplay(value) {
710
+ /**
711
+ * Autoplay
712
+ */ set autoplay(value) {
651
713
  this.setAttribute('autoplay', (!!value).toString());
652
714
  }
653
715
  get autoplay() {
@@ -657,13 +719,17 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
657
719
  }
658
720
  return false;
659
721
  }
660
- set background(value) {
722
+ /**
723
+ * Background color
724
+ */ set background(value) {
661
725
  this.setAttribute('background', value);
662
726
  }
663
727
  get background() {
664
728
  return this.getAttribute('background') || 'transparent';
665
729
  }
666
- set controls(value) {
730
+ /**
731
+ * Show controls
732
+ */ set controls(value) {
667
733
  this.setAttribute('controls', (!!value).toString());
668
734
  }
669
735
  get controls() {
@@ -673,7 +739,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
673
739
  }
674
740
  return false;
675
741
  }
676
- set count(value) {
742
+ /**
743
+ * Number of times to loop
744
+ */ set count(value) {
677
745
  this.setAttribute('count', value.toString());
678
746
  }
679
747
  get count() {
@@ -683,13 +751,17 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
683
751
  }
684
752
  return 0;
685
753
  }
686
- set description(value) {
754
+ /**
755
+ * Description for screen readers
756
+ */ set description(value) {
687
757
  this.setAttribute('description', value);
688
758
  }
689
759
  get description() {
690
760
  return this.getAttribute('description') || '';
691
761
  }
692
- set direction(value) {
762
+ /**
763
+ * Direction of animation
764
+ */ set direction(value) {
693
765
  this.setAttribute('direction', value.toString());
694
766
  }
695
767
  get direction() {
@@ -699,7 +771,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
699
771
  }
700
772
  return 1;
701
773
  }
702
- set hover(value) {
774
+ /**
775
+ * Whether to play on mouseover
776
+ */ set hover(value) {
703
777
  this.setAttribute('hover', value.toString());
704
778
  }
705
779
  get hover() {
@@ -709,7 +783,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
709
783
  }
710
784
  return false;
711
785
  }
712
- set intermission(value) {
786
+ /**
787
+ * Pause between loop intrations, in miliseconds
788
+ */ set intermission(value) {
713
789
  this.setAttribute('intermission', value.toString());
714
790
  }
715
791
  get intermission() {
@@ -719,7 +795,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
719
795
  }
720
796
  return 0;
721
797
  }
722
- set loop(value) {
798
+ /**
799
+ * Loop animation
800
+ */ set loop(value) {
723
801
  this.setAttribute('loop', (!!value).toString());
724
802
  }
725
803
  get loop() {
@@ -729,7 +807,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
729
807
  }
730
808
  return false;
731
809
  }
732
- set mode(value) {
810
+ /**
811
+ * Play mode
812
+ */ set mode(value) {
733
813
  this.setAttribute('mode', value.toString());
734
814
  }
735
815
  get mode() {
@@ -739,7 +819,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
739
819
  }
740
820
  return PlayMode.Normal;
741
821
  }
742
- set objectfit(value) {
822
+ /**
823
+ * Resizing to container
824
+ */ set objectfit(value) {
743
825
  this.setAttribute('objectfit', value);
744
826
  }
745
827
  get objectfit() {
@@ -749,7 +831,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
749
831
  }
750
832
  return ObjectFit.Contain;
751
833
  }
752
- set preserveAspectRatio(value) {
834
+ /**
835
+ * Resizing to container (Deprecated)
836
+ */ set preserveAspectRatio(value) {
753
837
  this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
754
838
  }
755
839
  get preserveAspectRatio() {
@@ -759,7 +843,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
759
843
  }
760
844
  return null;
761
845
  }
762
- set renderer(value) {
846
+ /**
847
+ * Renderer to use: svg, canvas or html
848
+ */ set renderer(value) {
763
849
  this.setAttribute('renderer', value);
764
850
  }
765
851
  get renderer() {
@@ -769,7 +855,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
769
855
  }
770
856
  return 'svg';
771
857
  }
772
- set simple(value) {
858
+ /**
859
+ * Hide advanced controls
860
+ */ set simple(value) {
773
861
  this.setAttribute('simple', value.toString());
774
862
  }
775
863
  get simple() {
@@ -779,7 +867,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
779
867
  }
780
868
  return false;
781
869
  }
782
- set speed(value) {
870
+ /**
871
+ * Speed
872
+ */ set speed(value) {
783
873
  this.setAttribute('speed', value?.toString());
784
874
  }
785
875
  get speed() {
@@ -789,13 +879,17 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
789
879
  }
790
880
  return 1;
791
881
  }
792
- set src(value) {
882
+ /**
883
+ * Source, either path or JSON string
884
+ */ set src(value) {
793
885
  this.setAttribute('src', value || '');
794
886
  }
795
887
  get src() {
796
888
  return this.getAttribute('src');
797
889
  }
798
- set subframe(value) {
890
+ /**
891
+ * Subframe
892
+ */ set subframe(value) {
799
893
  this.setAttribute('subframe', (!!value).toString());
800
894
  }
801
895
  get subframe() {
@@ -805,29 +899,45 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
805
899
  }
806
900
  return false;
807
901
  }
808
- getMultiAnimationSettings() {
902
+ /**
903
+ * Get Multi-animation settings
904
+ * @returns { AnimationSettings[] }
905
+ */ getMultiAnimationSettings() {
809
906
  return this._multiAnimationSettings;
810
907
  }
811
- setMultiAnimationSettings(settings) {
908
+ /**
909
+ * Set Multi-animation settings
910
+ * @param { AnimationSettings[] } settings
911
+ */ setMultiAnimationSettings(settings) {
812
912
  if (!this._lottieInstance) {
813
913
  return;
814
914
  }
815
915
  this._multiAnimationSettings = settings;
816
916
  }
817
- setSegment(segment) {
917
+ /**
918
+ * Set playback segment
919
+ * @param { AnimationSegment } settings
920
+ */ setSegment(segment) {
818
921
  if (!this._lottieInstance) {
819
922
  return;
820
923
  }
821
924
  this._segment = segment;
822
925
  }
823
- getSegment() {
926
+ /**
927
+ * Get playback segment
928
+ * @returns { AnimationSegment }
929
+ */ getSegment() {
824
930
  return this._segment;
825
931
  }
826
- _getOptions() {
932
+ /**
933
+ * Get options from props
934
+ * @returns { AnimationConfig }
935
+ */ _getOptions() {
827
936
  if (!this._container) {
828
937
  throw new Error('Container not rendered');
829
938
  }
830
939
  const preserveAspectRatio = this.preserveAspectRatio ?? (this.objectfit && aspectRatio(this.objectfit)), currentAnimationSettings = this._multiAnimationSettings?.length ? this._multiAnimationSettings?.[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest.animations?.[this._currentAnimation];
940
+ // Loop
831
941
  let loop = !!this.loop;
832
942
  if (currentAnimationManifest.loop !== undefined && this.loop === undefined) {
833
943
  loop = !!currentAnimationManifest.loop;
@@ -835,6 +945,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
835
945
  if (currentAnimationSettings?.loop !== undefined) {
836
946
  loop = !!currentAnimationSettings.loop;
837
947
  }
948
+ // Autoplay
838
949
  let autoplay = !!this.autoplay;
839
950
  if (currentAnimationManifest.autoplay !== undefined && this.autoplay === undefined) {
840
951
  autoplay = !!currentAnimationManifest.autoplay;
@@ -845,6 +956,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
845
956
  if (this.animateOnScroll) {
846
957
  autoplay = false;
847
958
  }
959
+ // Segment
848
960
  let initialSegment = this._segment;
849
961
  if (this._segment?.every((val)=>val > 0)) {
850
962
  initialSegment = [
@@ -890,7 +1002,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
890
1002
  }
891
1003
  return options;
892
1004
  }
893
- _addIntersectionObserver() {
1005
+ /**
1006
+ * Add IntersectionObserver
1007
+ */ _addIntersectionObserver() {
894
1008
  if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
895
1009
  return;
896
1010
  }
@@ -914,10 +1028,13 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
914
1028
  });
915
1029
  this._intersectionObserver.observe(this._container);
916
1030
  }
917
- async load(src) {
1031
+ /**
1032
+ * Initialize Lottie Web player
1033
+ */ async load(src) {
918
1034
  if (!this.shadowRoot || !src) {
919
1035
  return;
920
1036
  }
1037
+ // Load the resource
921
1038
  try {
922
1039
  const { animations, isDotLottie, manifest } = await getAnimationData(src);
923
1040
  if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
@@ -943,6 +1060,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
943
1060
  }
944
1061
  ]
945
1062
  };
1063
+ // Clear previous animation, if any
946
1064
  if (this._lottieInstance) {
947
1065
  this._lottieInstance.destroy();
948
1066
  }
@@ -950,6 +1068,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
950
1068
  if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings?.[this._currentAnimation]?.autoplay)) {
951
1069
  this.playerState = PlayerState.Playing;
952
1070
  }
1071
+ // Initialize lottie player and load animation
953
1072
  this._lottieInstance = Lottie.default.loadAnimation({
954
1073
  ...this._getOptions(),
955
1074
  animationData: animations[this._currentAnimation]
@@ -962,9 +1081,11 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
962
1081
  }
963
1082
  this._addEventListeners();
964
1083
  const speed = this._multiAnimationSettings?.[this._currentAnimation]?.speed ?? this.speed ?? this._manifest.animations[this._currentAnimation].speed, direction = this._multiAnimationSettings?.[this._currentAnimation]?.direction ?? this.direction ?? this._manifest.animations[this._currentAnimation].direction ?? 1;
1084
+ // Set initial playback speed and direction
965
1085
  this._lottieInstance.setSpeed(speed);
966
1086
  this._lottieInstance.setDirection(direction);
967
1087
  this._lottieInstance.setSubframe(!!this.subframe);
1088
+ // Start playing if autoplay is enabled
968
1089
  if (this.autoplay || this.animateOnScroll) {
969
1090
  if (this.direction === -1) {
970
1091
  this.seek('99%');
@@ -978,10 +1099,14 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
978
1099
  this._addIntersectionObserver();
979
1100
  }
980
1101
  }
981
- getManifest() {
1102
+ /**
1103
+ * Get Lottie Manifest
1104
+ */ getManifest() {
982
1105
  return this._manifest;
983
1106
  }
984
- _toggleEventListeners(action) {
1107
+ /**
1108
+ * Toggle event listeners
1109
+ */ _toggleEventListeners(action) {
985
1110
  const method = action === 'add' ? 'addEventListener' : 'removeEventListener';
986
1111
  if (this._lottieInstance) {
987
1112
  this._lottieInstance[method]('enterFrame', this._enterFrame);
@@ -1010,17 +1135,22 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1010
1135
  });
1011
1136
  }
1012
1137
  }
1013
- _addEventListeners() {
1138
+ /**
1139
+ * Add event listeners
1140
+ */ _addEventListeners() {
1014
1141
  this._toggleEventListeners('add');
1015
1142
  }
1016
- _removeEventListeners() {
1143
+ /**
1144
+ * Remove event listeners
1145
+ */ _removeEventListeners() {
1017
1146
  this._toggleEventListeners('remove');
1018
1147
  }
1019
1148
  _loopComplete() {
1020
1149
  if (!this._lottieInstance) {
1021
1150
  return;
1022
1151
  }
1023
- const { playDirection, totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
1152
+ const { playDirection, // firstFrame,
1153
+ totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
1024
1154
  if (this.count) {
1025
1155
  if (this._isBounce) {
1026
1156
  this._playerState.count += 0.5;
@@ -1106,17 +1236,23 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1106
1236
  this.play();
1107
1237
  }
1108
1238
  }
1109
- _mouseEnter() {
1239
+ /**
1240
+ * Handle MouseEnter
1241
+ */ _mouseEnter() {
1110
1242
  if (this.hover && this.playerState !== PlayerState.Playing) {
1111
1243
  this.play();
1112
1244
  }
1113
1245
  }
1114
- _mouseLeave() {
1246
+ /**
1247
+ * Handle MouseLeave
1248
+ */ _mouseLeave() {
1115
1249
  if (this.hover && this.playerState === PlayerState.Playing) {
1116
1250
  this.stop();
1117
1251
  }
1118
1252
  }
1119
- _onVisibilityChange() {
1253
+ /**
1254
+ * Handle visibility change events
1255
+ */ _onVisibilityChange() {
1120
1256
  if (document.hidden && this.playerState === PlayerState.Playing) {
1121
1257
  this._freeze();
1122
1258
  return;
@@ -1125,7 +1261,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1125
1261
  this.play();
1126
1262
  }
1127
1263
  }
1128
- _handleScroll() {
1264
+ /**
1265
+ * Handle scroll
1266
+ */ _handleScroll() {
1129
1267
  if (!this.animateOnScroll || !this._lottieInstance) {
1130
1268
  return;
1131
1269
  }
@@ -1151,7 +1289,10 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1151
1289
  });
1152
1290
  }
1153
1291
  }
1154
- _handleSeekChange({ target }) {
1292
+ /**
1293
+ * Handles click and drag actions on the progress track
1294
+ * @param { Event & { HTMLInputElement } } event
1295
+ */ _handleSeekChange({ target }) {
1155
1296
  if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
1156
1297
  return;
1157
1298
  }
@@ -1169,7 +1310,16 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1169
1310
  ];
1170
1311
  return mandatory.every((field)=>Object.prototype.hasOwnProperty.call(json, field));
1171
1312
  }
1172
- async addAnimation(configs, fileName, shouldDownload = true) {
1313
+ /**
1314
+ * Creates a new dotLottie file, by combinig several animations
1315
+ * @param { [ AnimationConfig ] } configs
1316
+ * @param { string } fileName
1317
+ * @param { boolean } shouldDownload Whether to trigger a download in the browser.
1318
+ * If set to false the function returns an ArrayBuffer. Defaults to true.
1319
+ *
1320
+ */ async addAnimation(configs, fileName, shouldDownload = true) {
1321
+ // Initialize meta object for animation, with fallbacks for
1322
+ // when the method is called indepenently
1173
1323
  const { animations = [], manifest = {
1174
1324
  animations: this.src ? [
1175
1325
  {
@@ -1211,10 +1361,14 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1211
1361
  };
1212
1362
  }
1213
1363
  }
1214
- getLottie() {
1364
+ /**
1365
+ * Returns the lottie-web instance used in the component
1366
+ */ getLottie() {
1215
1367
  return this._lottieInstance;
1216
1368
  }
1217
- async play() {
1369
+ /**
1370
+ * Play
1371
+ */ async play() {
1218
1372
  if (!this._lottieInstance) {
1219
1373
  return;
1220
1374
  }
@@ -1228,7 +1382,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1228
1382
  this.playerState = PlayerState.Playing;
1229
1383
  }
1230
1384
  }
1231
- pause() {
1385
+ /**
1386
+ * Pause
1387
+ */ pause() {
1232
1388
  if (!this._lottieInstance) {
1233
1389
  return;
1234
1390
  }
@@ -1242,7 +1398,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1242
1398
  this.playerState = PlayerState.Paused;
1243
1399
  }
1244
1400
  }
1245
- stop() {
1401
+ /**
1402
+ * Stop
1403
+ */ stop() {
1246
1404
  if (!this._lottieInstance) {
1247
1405
  return;
1248
1406
  }
@@ -1257,7 +1415,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1257
1415
  this.playerState = PlayerState.Stopped;
1258
1416
  }
1259
1417
  }
1260
- destroy() {
1418
+ /**
1419
+ * Destroy animation and element
1420
+ */ destroy() {
1261
1421
  if (!this._lottieInstance) {
1262
1422
  return;
1263
1423
  }
@@ -1268,16 +1428,23 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1268
1428
  this.remove();
1269
1429
  document.removeEventListener('visibilitychange', this._onVisibilityChange);
1270
1430
  }
1271
- seek(value) {
1431
+ /**
1432
+ * Seek to a given frame
1433
+ * @param { number | string } value Frame to seek to
1434
+ */ seek(value) {
1272
1435
  if (!this._lottieInstance) {
1273
1436
  return;
1274
1437
  }
1438
+ // Extract frame number from either number or percentage value
1275
1439
  const matches = value.toString().match(/^([0-9]+)(%?)$/);
1276
1440
  if (!matches) {
1277
1441
  return;
1278
1442
  }
1443
+ // Calculate and set the frame number
1279
1444
  const frame = Math.round(matches[2] === '%' ? this._lottieInstance.totalFrames * Number(matches[1]) / 100 : Number(matches[1]));
1445
+ // Set seeker to new frame number
1280
1446
  this._seeker = frame;
1447
+ // Send lottie player to the new frame
1281
1448
  if (this.playerState === PlayerState.Playing || this.playerState === PlayerState.Frozen && this._playerState.prev === PlayerState.Playing) {
1282
1449
  this._lottieInstance.goToAndPlay(frame, true);
1283
1450
  this.playerState = PlayerState.Playing;
@@ -1286,10 +1453,13 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1286
1453
  this._lottieInstance.goToAndStop(frame, true);
1287
1454
  this._lottieInstance.pause();
1288
1455
  }
1289
- snapshot() {
1456
+ /**
1457
+ * Snapshot and download the current frame as SVG
1458
+ */ snapshot() {
1290
1459
  if (!this.shadowRoot || !this.src) {
1291
1460
  return;
1292
1461
  }
1462
+ // Get SVG element and serialize markup
1293
1463
  const svgElement = this.shadowRoot.querySelector('.animation svg'), data = svgElement instanceof Node ? new XMLSerializer().serializeToString(svgElement) : null;
1294
1464
  if (!data) {
1295
1465
  console.error('Could not serialize data');
@@ -1301,19 +1471,28 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1301
1471
  });
1302
1472
  return data;
1303
1473
  }
1304
- setSubframe(value) {
1474
+ /**
1475
+ * Toggles subframe, for more smooth animations
1476
+ * @param { boolean } value Whether animation uses subframe
1477
+ */ setSubframe(value) {
1305
1478
  if (!this._lottieInstance) {
1306
1479
  return;
1307
1480
  }
1308
1481
  this._lottieInstance.setSubframe(value);
1309
1482
  }
1310
- setCount(value) {
1483
+ /**
1484
+ * Dynamically set count for loops
1485
+ */ setCount(value) {
1311
1486
  if (!this._lottieInstance) {
1312
1487
  return;
1313
1488
  }
1314
1489
  this.count = value;
1315
1490
  }
1316
- _freeze() {
1491
+ /**
1492
+ * Freeze animation.
1493
+ * This internal state pauses animation and is used to differentiate between
1494
+ * user requested pauses and component instigated pauses.
1495
+ */ _freeze() {
1317
1496
  if (!this._lottieInstance) {
1318
1497
  return;
1319
1498
  }
@@ -1327,32 +1506,45 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1327
1506
  this.playerState = PlayerState.Frozen;
1328
1507
  }
1329
1508
  }
1330
- async reload() {
1509
+ /**
1510
+ * Reload animation
1511
+ */ async reload() {
1331
1512
  if (!this._lottieInstance || !this.src) {
1332
1513
  return;
1333
1514
  }
1334
1515
  this._lottieInstance.destroy();
1335
1516
  await this.load(this.src);
1336
1517
  }
1337
- setSpeed(value = 1) {
1518
+ /**
1519
+ * Set animation playback speed
1520
+ * @param { number } value Playback speed
1521
+ */ setSpeed(value = 1) {
1338
1522
  if (!this._lottieInstance) {
1339
1523
  return;
1340
1524
  }
1341
1525
  this._lottieInstance.setSpeed(value);
1342
1526
  }
1343
- setDirection(value) {
1527
+ /**
1528
+ * Animation play direction
1529
+ * @param { AnimationDirection } value Animation direction
1530
+ */ setDirection(value) {
1344
1531
  if (!this._lottieInstance) {
1345
1532
  return;
1346
1533
  }
1347
1534
  this._lottieInstance.setDirection(value);
1348
1535
  }
1349
- setLoop(value) {
1536
+ /**
1537
+ * Set loop
1538
+ * @param { boolean } value
1539
+ */ setLoop(value) {
1350
1540
  if (!this._lottieInstance) {
1351
1541
  return;
1352
1542
  }
1353
1543
  this._lottieInstance.setLoop(value);
1354
1544
  }
1355
- togglePlay() {
1545
+ /**
1546
+ * Toggle playing state
1547
+ */ togglePlay() {
1356
1548
  if (!this._lottieInstance) {
1357
1549
  return;
1358
1550
  }
@@ -1373,12 +1565,16 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1373
1565
  }
1374
1566
  return this._lottieInstance.goToAndPlay(0, true);
1375
1567
  }
1376
- toggleLoop() {
1568
+ /**
1569
+ * Toggle loop
1570
+ */ toggleLoop() {
1377
1571
  const val = !this.loop;
1378
1572
  this.loop = val;
1379
1573
  this.setLoop(val);
1380
1574
  }
1381
- toggleBoomerang() {
1575
+ /**
1576
+ * Toggle Boomerang
1577
+ */ toggleBoomerang() {
1382
1578
  const curr = this._multiAnimationSettings?.[this._currentAnimation];
1383
1579
  if (curr?.mode !== undefined) {
1384
1580
  if (curr.mode === PlayMode.Normal) {
@@ -1398,31 +1594,40 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1398
1594
  this.mode = PlayMode.Normal;
1399
1595
  this._isBounce = false;
1400
1596
  }
1401
- _toggleSettings(flag) {
1597
+ /**
1598
+ * Toggle show Settings
1599
+ */ _toggleSettings(flag) {
1402
1600
  if (flag === undefined) {
1403
1601
  this._isSettingsOpen = !this._isSettingsOpen;
1404
1602
  return;
1405
1603
  }
1406
1604
  this._isSettingsOpen = flag;
1407
1605
  }
1408
- _handleBlur() {
1606
+ /**
1607
+ * Handle blur
1608
+ */ _handleBlur() {
1409
1609
  setTimeout(()=>this._toggleSettings(false), 200);
1410
1610
  }
1411
1611
  _switchInstance(isPrevious = false) {
1612
+ // Bail early if there is not animation to play
1412
1613
  if (!this._animations[this._currentAnimation]) {
1413
1614
  return;
1414
1615
  }
1415
1616
  try {
1617
+ // Clear previous animation
1416
1618
  if (this._lottieInstance) {
1417
1619
  this._lottieInstance.destroy();
1418
1620
  }
1621
+ // Re-initialize lottie player
1419
1622
  this._lottieInstance = Lottie.default.loadAnimation({
1420
1623
  ...this._getOptions(),
1421
1624
  animationData: this._animations[this._currentAnimation]
1422
1625
  });
1626
+ // Check play mode for current animation
1423
1627
  if (this._multiAnimationSettings?.[this._currentAnimation]?.mode) {
1424
1628
  this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
1425
1629
  }
1630
+ // Remove event listeners to new Lottie instance, and add new
1426
1631
  this._removeEventListeners();
1427
1632
  this._addEventListeners();
1428
1633
  this.dispatchEvent(new CustomEvent(isPrevious ? PlayerEvents.Previous : PlayerEvents.Next));
@@ -1444,11 +1649,15 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1444
1649
  this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
1445
1650
  }
1446
1651
  }
1447
- next() {
1652
+ /**
1653
+ * Skip to next animation
1654
+ */ next() {
1448
1655
  this._currentAnimation++;
1449
1656
  this._switchInstance();
1450
1657
  }
1451
- prev() {
1658
+ /**
1659
+ * Skip to previous animation
1660
+ */ prev() {
1452
1661
  this._currentAnimation--;
1453
1662
  this._switchInstance(true);
1454
1663
  }
@@ -1470,21 +1679,40 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1470
1679
  shouldDownload
1471
1680
  });
1472
1681
  }
1473
- static get styles() {
1682
+ /**
1683
+ * Return the styles for the component
1684
+ */ static get styles() {
1474
1685
  const styleSheet = new CSSStyleSheet();
1475
1686
  styleSheet.replace(css_248z);
1476
1687
  return styleSheet;
1477
1688
  }
1478
1689
  constructor(){
1479
- super(), this._renderControls = renderControls, this._render = renderPlayer, this._multiAnimationSettings = [], this.playerState = PlayerState.Loading, this._isSettingsOpen = false, this._seeker = 0, this._currentAnimation = 0, this._lottieInstance = null, this._identifier = this.id || useId('dotlottie'), this._errorMessage = 'Something went wrong', this._isBounce = false, this._isDotLottie = false, this._playerState = {
1690
+ super(), this._renderControls = renderControls, this._render = renderPlayer, /**
1691
+ * Multi-animation settings
1692
+ */ this._multiAnimationSettings = [], /**
1693
+ * @state
1694
+ * Player state
1695
+ */ this.playerState = PlayerState.Loading, /**
1696
+ * @state
1697
+ * Whether settings toolbar is open
1698
+ */ this._isSettingsOpen = false, /**
1699
+ * @state
1700
+ * Seeker
1701
+ */ this._seeker = 0, /**
1702
+ * @state
1703
+ * Which animation to show, if several
1704
+ */ this._currentAnimation = 0, this._lottieInstance = null, this._identifier = this.id || useId('dotlottie'), this._errorMessage = 'Something went wrong', this._isBounce = false, this._isDotLottie = false, this._playerState = {
1480
1705
  count: 0,
1481
1706
  loaded: false,
1482
1707
  prev: PlayerState.Loading,
1483
1708
  scrollTimeout: null,
1484
1709
  scrollY: 0,
1485
1710
  visible: false
1486
- }, this._handleSettingsClick = ({ target })=>{
1711
+ }, /**
1712
+ * Handle settings click event
1713
+ */ this._handleSettingsClick = ({ target })=>{
1487
1714
  this._toggleSettings();
1715
+ // Because Safari does not add focus on click, we need to add it manually, so the onblur event will fire
1488
1716
  if (target instanceof HTMLElement) {
1489
1717
  target.focus();
1490
1718
  }
@@ -1521,7 +1749,10 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1521
1749
  }
1522
1750
  };
1523
1751
 
1524
- globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
1752
+ /**
1753
+ * Expose DotLottiePlayer class as global variable
1754
+ * @returns { DotLottiePlayer }
1755
+ */ globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
1525
1756
  const tagName = 'dotlottie-player';
1526
1757
  if (!isServer()) {
1527
1758
  customElements.define('dotlottie-player', DotLottiePlayer);