@aarsteinmedia/dotlottie-player 4.0.3 → 4.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cjs/index.js CHANGED
@@ -100,12 +100,20 @@ const addExt = (ext, str)=>{
100
100
  default:
101
101
  return 'xMidYMid meet';
102
102
  }
103
- }, base64ToU8 = (str)=>fflate.strToU8(isServer() ? Buffer.from(parseBase64(str), 'base64').toString('binary') : atob(parseBase64(str)), true), createDotLottie = async ({ animations, fileName, manifest, shouldDownload = true })=>{
103
+ }, /**
104
+ * Convert Base64 encoded string to Uint8Array
105
+ * @param { string } str Base64 encoded string
106
+ * @returns { Uint8Array } UTF-8/Latin-1 binary
107
+ */ base64ToU8 = (str)=>fflate.strToU8(isServer() ? Buffer.from(parseBase64(str), 'base64').toString('binary') : atob(parseBase64(str)), true), /**
108
+ * Convert a JSON Lottie to dotLottie or combine several animations and download new dotLottie file in your browser.
109
+ */ createDotLottie = async ({ animations, fileName, manifest, shouldDownload = true })=>{
104
110
  try {
111
+ // Input validation
105
112
  if (!animations?.length || !manifest) {
106
113
  throw new Error(`Missing or malformed required parameter(s):\n ${animations?.length ? '- manifest\n' : ''} ${manifest ? '- animations\n' : ''}`);
107
114
  }
108
- const manifestCompressionLevel = 0, animationCompressionLevel = 9, name = addExt('lottie', fileName) || `${useId()}.lottie`, dotlottie = {
115
+ const manifestCompressionLevel = 0, animationCompressionLevel = 9, // Prepare the dotLottie file
116
+ name = addExt('lottie', fileName) || `${useId()}.lottie`, dotlottie = {
109
117
  'manifest.json': [
110
118
  fflate.strToU8(JSON.stringify(manifest), true),
111
119
  {
@@ -113,14 +121,19 @@ const addExt = (ext, str)=>{
113
121
  }
114
122
  ]
115
123
  };
124
+ // Add animations and assets to the dotLottie file
116
125
  for (const [i, animation] of animations.entries()){
117
126
  for (const asset of animation.assets ?? []){
118
127
  if (!asset.p || !isImage(asset) && !isAudio(asset)) {
119
128
  continue;
120
129
  }
121
- 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);
130
+ const { p: file, u: path } = asset, // Original asset.id caused issues with multianimations
131
+ 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
132
+ dataURL = isEncoded ? file : await fileToBase64(path ? path.endsWith('/') && `${path}${file}` || `${path}/${file}` : file);
122
133
  asset.p = `${assetId}.${ext}`;
134
+ // Asset is embedded, so path empty string
123
135
  asset.u = '';
136
+ // Asset is encoded
124
137
  asset.e = 1;
125
138
  dotlottie[`${isAudio(asset) ? 'audio' : 'images'}/${assetId}.${ext}`] = [
126
139
  base64ToU8(dataURL),
@@ -157,7 +170,11 @@ const addExt = (ext, str)=>{
157
170
  } catch (err) {
158
171
  console.error(`❌ ${handleErrors(err).message}`);
159
172
  }
160
- }, download = (data, options)=>{
173
+ }, /**
174
+ * Download file, either SVG or dotLottie.
175
+ * @param { string } data The data to be downloaded
176
+ * @param { string } name Don't include file extension in the filename
177
+ */ download = (data, options)=>{
161
178
  const blob = new Blob([
162
179
  data
163
180
  ], {
@@ -214,7 +231,11 @@ const addExt = (ext, str)=>{
214
231
  error.status = result.status;
215
232
  throw error;
216
233
  }
217
- const ext = getExt(input);
234
+ /**
235
+ * Check if file is JSON, first by parsing file name for extension,
236
+ * then – if filename has no extension – by cloning the response
237
+ * and parsing it for content.
238
+ */ const ext = getExt(input);
218
239
  if (ext === 'json' || !ext) {
219
240
  if (ext) {
220
241
  const lottie = await result.json();
@@ -236,9 +257,8 @@ const addExt = (ext, str)=>{
236
257
  isDotLottie: false,
237
258
  manifest: undefined
238
259
  };
239
- } catch (e) {
240
- console.warn(e);
241
- }
260
+ } catch (_e) {
261
+ /* empty */ }
242
262
  }
243
263
  const { data, manifest } = await getLottieJSON(result);
244
264
  return {
@@ -267,7 +287,10 @@ const addExt = (ext, str)=>{
267
287
  });
268
288
  });
269
289
  return arrayBuffer;
270
- }, getExt = (str)=>{
290
+ }, /**
291
+ * Get extension from filename, URL or path
292
+ * @param { string } str Filename, URL or path
293
+ */ getExt = (str)=>{
271
294
  if (typeof str !== 'string' || !str || !hasExt(str)) {
272
295
  return;
273
296
  }
@@ -275,9 +298,16 @@ const addExt = (ext, str)=>{
275
298
  }, getExtFromB64 = (str)=>{
276
299
  const mime = str.split(':')[1].split(';')[0], ext = mime.split('/')[1].split('+')[0];
277
300
  return ext;
278
- }, getFilename = (src, keepExt)=>{
301
+ }, /**
302
+ * Parse URL to get filename
303
+ * @param { string } src The url string
304
+ * @param { boolean } keepExt Whether to include file extension
305
+ * @returns { string } Filename, in lowercase
306
+ */ getFilename = (src, keepExt)=>{
307
+ // Because the regex strips all special characters, we need to extract the file extension, so we can add it later if we need it
279
308
  getExt(src);
280
- return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replace(/\W+/g, '-')}${''}`;
309
+ return `${src.split('/').pop()?.replace(/\.[^.]*$/, '').replace(/\W+/g, '-')}${''}` // .toLowerCase()
310
+ ;
281
311
  }, getLottieJSON = async (resp)=>{
282
312
  const unzipped = await unzip(resp), manifest = getManifest(unzipped), data = [], toResolve = [];
283
313
  for (const { id } of manifest.animations){
@@ -369,7 +399,7 @@ const addExt = (ext, str)=>{
369
399
  await Promise.all(toResolve);
370
400
  }, unzip = async (resp)=>{
371
401
  const u8 = new Uint8Array(await resp.arrayBuffer()), unzipped = await new Promise((resolve, reject)=>{
372
- fflate.unzip(u8, (err, file)=>{
402
+ fflate.unzip(u8, /* { filter }, */ (err, file)=>{
373
403
  if (err) {
374
404
  reject(err);
375
405
  }
@@ -382,15 +412,19 @@ const addExt = (ext, str)=>{
382
412
  return `${prefix ?? `:${s4()}`}_${s4()}`;
383
413
  };
384
414
 
385
- function renderPlayer() {
386
- 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>`;
415
+ /**
416
+ * Render Player
417
+ */ function renderPlayer() {
418
+ 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>`;
387
419
  this.shadow.adoptedStyleSheets = [
388
420
  DotLottiePlayer.styles
389
421
  ];
390
422
  this.shadow.appendChild(this.template.content.cloneNode(true));
391
423
  }
392
424
 
393
- function renderControls() {
425
+ /**
426
+ * Render Controls
427
+ */ function renderControls() {
394
428
  const slot = this.shadow.querySelector('slot[name=controls]');
395
429
  if (!slot) {
396
430
  return;
@@ -399,7 +433,7 @@ function renderControls() {
399
433
  slot.innerHTML = '';
400
434
  return;
401
435
  }
402
- 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>`;
436
+ 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>`;
403
437
  const togglePlay = this.shadow.querySelector('.togglePlay');
404
438
  if (togglePlay instanceof HTMLButtonElement) {
405
439
  togglePlay.onclick = this.togglePlay;
@@ -436,7 +470,7 @@ function renderControls() {
436
470
  }
437
471
  const snapshot = this.shadow.querySelector('.snapshot');
438
472
  if (snapshot instanceof HTMLButtonElement) {
439
- snapshot.onclick = this.snapshot;
473
+ snapshot.onclick = ()=>this.snapshot(true);
440
474
  }
441
475
  const toggleSettings = this.shadow.querySelector('.toggleSettings');
442
476
  if (toggleSettings instanceof HTMLButtonElement) {
@@ -446,8 +480,14 @@ function renderControls() {
446
480
  }
447
481
  }
448
482
 
449
- const UPDATE_ON_CONNECTED = Symbol('UPDATE_ON_CONNECTED');
483
+ /**
484
+ * Credit to:
485
+ * @author Leonardo Favre <https://github.com/leofavre/observed-properties>
486
+ * @description Enhanced HTML element with reactive state handlers
487
+ */ /* eslint-disable @typescript-eslint/ban-ts-comment */ const UPDATE_ON_CONNECTED = Symbol('UPDATE_ON_CONNECTED');
450
488
  if (isServer()) {
489
+ // Mock HTMLElement for server-side rendering
490
+ // @ts-ignore
451
491
  global.HTMLElement = class EmptyHTMLElement {
452
492
  };
453
493
  }
@@ -468,6 +508,7 @@ let EnhancedElement = class EnhancedElement extends HTMLElement {
468
508
  }
469
509
  constructor(){
470
510
  super();
511
+ // @ts-ignore
471
512
  const { observedProperties = [] } = this.constructor;
472
513
  if (UPDATE_ON_CONNECTED in this) {
473
514
  this[UPDATE_ON_CONNECTED] = [];
@@ -475,6 +516,7 @@ let EnhancedElement = class EnhancedElement extends HTMLElement {
475
516
  if ('propertyChangedCallback' in this && typeof this.propertyChangedCallback === 'function') {
476
517
  for (const propName of observedProperties){
477
518
  const initialValue = this[propName], CACHED_VALUE = Symbol(propName);
519
+ // @ts-ignore
478
520
  this[CACHED_VALUE] = initialValue;
479
521
  Object.defineProperty(this, propName, {
480
522
  get () {
@@ -496,34 +538,46 @@ let EnhancedElement = class EnhancedElement extends HTMLElement {
496
538
  }
497
539
  };
498
540
 
499
- 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$1={".":{"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$1="./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$1,main:main,unpkg:unpkg,module:module$1,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};
541
+ var $schema="https://json.schemastore.org/package";var name="@aarsteinmedia/dotlottie-player";var version="4.0.5";var description="Web Component for playing Lottie animations in your web app. Previously @johanaarstein/dotlottie-player";var exports$1={".":{"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$1="./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.14.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.7","@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.14.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.6",stylelint:"^16.10.0","stylelint-config-standard-scss":"^13.1.0","tsc-alias":"^1.8.10",tslib:"^2.8.1",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$1,main:main,unpkg:unpkg,module:module$1,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};
500
542
 
501
543
  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}";
502
544
 
503
545
  let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
504
- async connectedCallback() {
546
+ /**
547
+ * Initialize everything on component first render
548
+ */ async connectedCallback() {
505
549
  super.connectedCallback();
506
550
  this._render();
507
551
  this._container = this.shadow.querySelector('.animation');
508
552
  this._renderControls();
553
+ // Add listener for Visibility API's change event.
509
554
  if (typeof document.hidden !== 'undefined') {
510
555
  document.addEventListener('visibilitychange', this._onVisibilityChange);
511
556
  }
557
+ // Add intersection observer for detecting component being out-of-view.
512
558
  this._addIntersectionObserver();
559
+ // Setup lottie player
513
560
  await this.load(this.src);
514
561
  this.dispatchEvent(new CustomEvent(PlayerEvents.Rendered));
515
562
  }
516
- disconnectedCallback() {
563
+ /**
564
+ * Cleanup on component destroy
565
+ */ disconnectedCallback() {
566
+ // Remove intersection observer for detecting component being out-of-view
517
567
  if (this._intersectionObserver) {
518
568
  this._intersectionObserver.disconnect();
519
569
  this._intersectionObserver = undefined;
520
570
  }
571
+ // Destroy the animation instance
521
572
  if (this._lottieInstance) {
522
573
  this._lottieInstance.destroy();
523
574
  }
575
+ // Remove the attached Visibility API's change event listener
524
576
  document.removeEventListener('visibilitychange', this._onVisibilityChange);
525
577
  }
526
- static get observedAttributes() {
578
+ /**
579
+ * Attributes to observe
580
+ */ static get observedAttributes() {
527
581
  return [
528
582
  'animateOnScroll',
529
583
  'autoplay',
@@ -537,7 +591,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
537
591
  'subframe'
538
592
  ];
539
593
  }
540
- async attributeChangedCallback(name, _oldValue, value) {
594
+ /**
595
+ * Runs when the value of an attribute is changed on the component
596
+ */ async attributeChangedCallback(name, _oldValue, value) {
541
597
  if (!this._lottieInstance) {
542
598
  return;
543
599
  }
@@ -616,6 +672,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
616
672
  '_animations'
617
673
  ];
618
674
  }
675
+ // name: string, oldValue: string, newValue: string
619
676
  propertyChangedCallback(name, _oldValue, value) {
620
677
  if (!this.shadow) {
621
678
  return;
@@ -628,9 +685,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
628
685
  togglePlay.dataset.active = (value === PlayerState.Playing || value === PlayerState.Paused).toString();
629
686
  stop.dataset.active = (value === PlayerState.Stopped).toString();
630
687
  if (value === PlayerState.Playing) {
631
- 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>`;
688
+ 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>`;
632
689
  } else {
633
- 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>`;
690
+ 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>`;
634
691
  }
635
692
  }
636
693
  if (name === '_seeker' && typeof value === 'number') {
@@ -660,7 +717,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
660
717
  convert.hidden = this._isDotLottie;
661
718
  }
662
719
  }
663
- set animateOnScroll(value) {
720
+ /**
721
+ * Whether to trigger next frame with scroll
722
+ */ set animateOnScroll(value) {
664
723
  this.setAttribute('animateOnScroll', (!!value).toString());
665
724
  }
666
725
  get animateOnScroll() {
@@ -670,7 +729,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
670
729
  }
671
730
  return false;
672
731
  }
673
- set autoplay(value) {
732
+ /**
733
+ * Autoplay
734
+ */ set autoplay(value) {
674
735
  this.setAttribute('autoplay', (!!value).toString());
675
736
  }
676
737
  get autoplay() {
@@ -680,13 +741,17 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
680
741
  }
681
742
  return false;
682
743
  }
683
- set background(value) {
744
+ /**
745
+ * Background color
746
+ */ set background(value) {
684
747
  this.setAttribute('background', value);
685
748
  }
686
749
  get background() {
687
750
  return this.getAttribute('background') || 'transparent';
688
751
  }
689
- set controls(value) {
752
+ /**
753
+ * Show controls
754
+ */ set controls(value) {
690
755
  this.setAttribute('controls', (!!value).toString());
691
756
  }
692
757
  get controls() {
@@ -696,7 +761,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
696
761
  }
697
762
  return false;
698
763
  }
699
- set count(value) {
764
+ /**
765
+ * Number of times to loop
766
+ */ set count(value) {
700
767
  this.setAttribute('count', value.toString());
701
768
  }
702
769
  get count() {
@@ -706,13 +773,17 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
706
773
  }
707
774
  return 0;
708
775
  }
709
- set description(value) {
776
+ /**
777
+ * Description for screen readers
778
+ */ set description(value) {
710
779
  this.setAttribute('description', value);
711
780
  }
712
781
  get description() {
713
782
  return this.getAttribute('description') || '';
714
783
  }
715
- set direction(value) {
784
+ /**
785
+ * Direction of animation
786
+ */ set direction(value) {
716
787
  this.setAttribute('direction', value.toString());
717
788
  }
718
789
  get direction() {
@@ -722,7 +793,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
722
793
  }
723
794
  return 1;
724
795
  }
725
- set hover(value) {
796
+ /**
797
+ * Whether to play on mouseover
798
+ */ set hover(value) {
726
799
  this.setAttribute('hover', value.toString());
727
800
  }
728
801
  get hover() {
@@ -732,7 +805,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
732
805
  }
733
806
  return false;
734
807
  }
735
- set intermission(value) {
808
+ /**
809
+ * Pause between loop intrations, in miliseconds
810
+ */ set intermission(value) {
736
811
  this.setAttribute('intermission', value.toString());
737
812
  }
738
813
  get intermission() {
@@ -742,7 +817,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
742
817
  }
743
818
  return 0;
744
819
  }
745
- set loop(value) {
820
+ /**
821
+ * Loop animation
822
+ */ set loop(value) {
746
823
  this.setAttribute('loop', (!!value).toString());
747
824
  }
748
825
  get loop() {
@@ -752,7 +829,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
752
829
  }
753
830
  return false;
754
831
  }
755
- set mode(value) {
832
+ /**
833
+ * Play mode
834
+ */ set mode(value) {
756
835
  this.setAttribute('mode', value.toString());
757
836
  }
758
837
  get mode() {
@@ -762,7 +841,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
762
841
  }
763
842
  return PlayMode.Normal;
764
843
  }
765
- set objectfit(value) {
844
+ /**
845
+ * Resizing to container
846
+ */ set objectfit(value) {
766
847
  this.setAttribute('objectfit', value);
767
848
  }
768
849
  get objectfit() {
@@ -772,7 +853,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
772
853
  }
773
854
  return ObjectFit.Contain;
774
855
  }
775
- set preserveAspectRatio(value) {
856
+ /**
857
+ * Resizing to container (Deprecated)
858
+ */ set preserveAspectRatio(value) {
776
859
  this.setAttribute('preserveAspectRatio', value || PreserveAspectRatio.Contain);
777
860
  }
778
861
  get preserveAspectRatio() {
@@ -782,7 +865,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
782
865
  }
783
866
  return null;
784
867
  }
785
- set renderer(value) {
868
+ /**
869
+ * Renderer to use: svg, canvas or html
870
+ */ set renderer(value) {
786
871
  this.setAttribute('renderer', value);
787
872
  }
788
873
  get renderer() {
@@ -792,7 +877,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
792
877
  }
793
878
  return 'svg';
794
879
  }
795
- set simple(value) {
880
+ /**
881
+ * Hide advanced controls
882
+ */ set simple(value) {
796
883
  this.setAttribute('simple', value.toString());
797
884
  }
798
885
  get simple() {
@@ -802,7 +889,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
802
889
  }
803
890
  return false;
804
891
  }
805
- set speed(value) {
892
+ /**
893
+ * Speed
894
+ */ set speed(value) {
806
895
  this.setAttribute('speed', value?.toString());
807
896
  }
808
897
  get speed() {
@@ -812,13 +901,17 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
812
901
  }
813
902
  return 1;
814
903
  }
815
- set src(value) {
904
+ /**
905
+ * Source, either path or JSON string
906
+ */ set src(value) {
816
907
  this.setAttribute('src', value || '');
817
908
  }
818
909
  get src() {
819
910
  return this.getAttribute('src');
820
911
  }
821
- set subframe(value) {
912
+ /**
913
+ * Subframe
914
+ */ set subframe(value) {
822
915
  this.setAttribute('subframe', (!!value).toString());
823
916
  }
824
917
  get subframe() {
@@ -828,29 +921,45 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
828
921
  }
829
922
  return false;
830
923
  }
831
- getMultiAnimationSettings() {
924
+ /**
925
+ * Get Multi-animation settings
926
+ * @returns { AnimationSettings[] }
927
+ */ getMultiAnimationSettings() {
832
928
  return this._multiAnimationSettings;
833
929
  }
834
- setMultiAnimationSettings(settings) {
930
+ /**
931
+ * Set Multi-animation settings
932
+ * @param { AnimationSettings[] } settings
933
+ */ setMultiAnimationSettings(settings) {
835
934
  if (!this._lottieInstance) {
836
935
  return;
837
936
  }
838
937
  this._multiAnimationSettings = settings;
839
938
  }
840
- setSegment(segment) {
939
+ /**
940
+ * Set playback segment
941
+ * @param { AnimationSegment } settings
942
+ */ setSegment(segment) {
841
943
  if (!this._lottieInstance) {
842
944
  return;
843
945
  }
844
946
  this._segment = segment;
845
947
  }
846
- getSegment() {
948
+ /**
949
+ * Get playback segment
950
+ * @returns { AnimationSegment }
951
+ */ getSegment() {
847
952
  return this._segment;
848
953
  }
849
- _getOptions() {
954
+ /**
955
+ * Get options from props
956
+ * @returns { AnimationConfig }
957
+ */ _getOptions() {
850
958
  if (!this._container) {
851
959
  throw new Error('Container not rendered');
852
960
  }
853
961
  const preserveAspectRatio = this.preserveAspectRatio ?? (this.objectfit && aspectRatio(this.objectfit)), currentAnimationSettings = this._multiAnimationSettings?.length ? this._multiAnimationSettings?.[this._currentAnimation] : undefined, currentAnimationManifest = this._manifest.animations?.[this._currentAnimation];
962
+ // Loop
854
963
  let loop = !!this.loop;
855
964
  if (currentAnimationManifest.loop !== undefined && this.loop === undefined) {
856
965
  loop = !!currentAnimationManifest.loop;
@@ -858,6 +967,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
858
967
  if (currentAnimationSettings?.loop !== undefined) {
859
968
  loop = !!currentAnimationSettings.loop;
860
969
  }
970
+ // Autoplay
861
971
  let autoplay = !!this.autoplay;
862
972
  if (currentAnimationManifest.autoplay !== undefined && this.autoplay === undefined) {
863
973
  autoplay = !!currentAnimationManifest.autoplay;
@@ -868,6 +978,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
868
978
  if (this.animateOnScroll) {
869
979
  autoplay = false;
870
980
  }
981
+ // Segment
871
982
  let initialSegment = this._segment;
872
983
  if (this._segment?.every((val)=>val > 0)) {
873
984
  initialSegment = [
@@ -913,7 +1024,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
913
1024
  }
914
1025
  return options;
915
1026
  }
916
- _addIntersectionObserver() {
1027
+ /**
1028
+ * Add IntersectionObserver
1029
+ */ _addIntersectionObserver() {
917
1030
  if (!this._container || this._intersectionObserver || !('IntersectionObserver' in window)) {
918
1031
  return;
919
1032
  }
@@ -937,10 +1050,13 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
937
1050
  });
938
1051
  this._intersectionObserver.observe(this._container);
939
1052
  }
940
- async load(src) {
1053
+ /**
1054
+ * Initialize Lottie Web player
1055
+ */ async load(src) {
941
1056
  if (!this.shadowRoot || !src) {
942
1057
  return;
943
1058
  }
1059
+ // Load the resource
944
1060
  try {
945
1061
  const { animations, isDotLottie, manifest } = await getAnimationData(src);
946
1062
  if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
@@ -966,6 +1082,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
966
1082
  }
967
1083
  ]
968
1084
  };
1085
+ // Clear previous animation, if any
969
1086
  if (this._lottieInstance) {
970
1087
  this._lottieInstance.destroy();
971
1088
  }
@@ -973,6 +1090,7 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
973
1090
  if (!this.animateOnScroll && (this.autoplay || this._multiAnimationSettings?.[this._currentAnimation]?.autoplay)) {
974
1091
  this.playerState = PlayerState.Playing;
975
1092
  }
1093
+ // Initialize lottie player and load animation
976
1094
  this._lottieInstance = Lottie__namespace.default.loadAnimation({
977
1095
  ...this._getOptions(),
978
1096
  animationData: animations[this._currentAnimation]
@@ -985,9 +1103,11 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
985
1103
  }
986
1104
  this._addEventListeners();
987
1105
  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;
1106
+ // Set initial playback speed and direction
988
1107
  this._lottieInstance.setSpeed(speed);
989
1108
  this._lottieInstance.setDirection(direction);
990
1109
  this._lottieInstance.setSubframe(!!this.subframe);
1110
+ // Start playing if autoplay is enabled
991
1111
  if (this.autoplay || this.animateOnScroll) {
992
1112
  if (this.direction === -1) {
993
1113
  this.seek('99%');
@@ -1001,10 +1121,14 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1001
1121
  this._addIntersectionObserver();
1002
1122
  }
1003
1123
  }
1004
- getManifest() {
1124
+ /**
1125
+ * Get Lottie Manifest
1126
+ */ getManifest() {
1005
1127
  return this._manifest;
1006
1128
  }
1007
- _toggleEventListeners(action) {
1129
+ /**
1130
+ * Toggle event listeners
1131
+ */ _toggleEventListeners(action) {
1008
1132
  const method = action === 'add' ? 'addEventListener' : 'removeEventListener';
1009
1133
  if (this._lottieInstance) {
1010
1134
  this._lottieInstance[method]('enterFrame', this._enterFrame);
@@ -1033,17 +1157,22 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1033
1157
  });
1034
1158
  }
1035
1159
  }
1036
- _addEventListeners() {
1160
+ /**
1161
+ * Add event listeners
1162
+ */ _addEventListeners() {
1037
1163
  this._toggleEventListeners('add');
1038
1164
  }
1039
- _removeEventListeners() {
1165
+ /**
1166
+ * Remove event listeners
1167
+ */ _removeEventListeners() {
1040
1168
  this._toggleEventListeners('remove');
1041
1169
  }
1042
1170
  _loopComplete() {
1043
1171
  if (!this._lottieInstance) {
1044
1172
  return;
1045
1173
  }
1046
- const { playDirection, totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
1174
+ const { playDirection, // firstFrame,
1175
+ totalFrames } = this._lottieInstance, inPoint = this._segment ? this._segment[0] : 0, outPoint = this._segment ? this._segment[0] : totalFrames;
1047
1176
  if (this.count) {
1048
1177
  if (this._isBounce) {
1049
1178
  this._playerState.count += 0.5;
@@ -1129,17 +1258,23 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1129
1258
  this.play();
1130
1259
  }
1131
1260
  }
1132
- _mouseEnter() {
1261
+ /**
1262
+ * Handle MouseEnter
1263
+ */ _mouseEnter() {
1133
1264
  if (this.hover && this.playerState !== PlayerState.Playing) {
1134
1265
  this.play();
1135
1266
  }
1136
1267
  }
1137
- _mouseLeave() {
1268
+ /**
1269
+ * Handle MouseLeave
1270
+ */ _mouseLeave() {
1138
1271
  if (this.hover && this.playerState === PlayerState.Playing) {
1139
1272
  this.stop();
1140
1273
  }
1141
1274
  }
1142
- _onVisibilityChange() {
1275
+ /**
1276
+ * Handle visibility change events
1277
+ */ _onVisibilityChange() {
1143
1278
  if (document.hidden && this.playerState === PlayerState.Playing) {
1144
1279
  this._freeze();
1145
1280
  return;
@@ -1148,7 +1283,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1148
1283
  this.play();
1149
1284
  }
1150
1285
  }
1151
- _handleScroll() {
1286
+ /**
1287
+ * Handle scroll
1288
+ */ _handleScroll() {
1152
1289
  if (!this.animateOnScroll || !this._lottieInstance) {
1153
1290
  return;
1154
1291
  }
@@ -1174,7 +1311,10 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1174
1311
  });
1175
1312
  }
1176
1313
  }
1177
- _handleSeekChange({ target }) {
1314
+ /**
1315
+ * Handles click and drag actions on the progress track
1316
+ * @param { Event & { HTMLInputElement } } event
1317
+ */ _handleSeekChange({ target }) {
1178
1318
  if (!(target instanceof HTMLInputElement) || !this._lottieInstance || isNaN(Number(target.value))) {
1179
1319
  return;
1180
1320
  }
@@ -1192,7 +1332,16 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1192
1332
  ];
1193
1333
  return mandatory.every((field)=>Object.prototype.hasOwnProperty.call(json, field));
1194
1334
  }
1195
- async addAnimation(configs, fileName, shouldDownload = true) {
1335
+ /**
1336
+ * Creates a new dotLottie file, by combinig several animations
1337
+ * @param { [ AnimationConfig ] } configs
1338
+ * @param { string } fileName
1339
+ * @param { boolean } shouldDownload Whether to trigger a download in the browser.
1340
+ * If set to false the function returns an ArrayBuffer. Defaults to true.
1341
+ *
1342
+ */ async addAnimation(configs, fileName, shouldDownload = true) {
1343
+ // Initialize meta object for animation, with fallbacks for
1344
+ // when the method is called indepenently
1196
1345
  const { animations = [], manifest = {
1197
1346
  animations: this.src ? [
1198
1347
  {
@@ -1234,10 +1383,14 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1234
1383
  };
1235
1384
  }
1236
1385
  }
1237
- getLottie() {
1386
+ /**
1387
+ * Returns the lottie-web instance used in the component
1388
+ */ getLottie() {
1238
1389
  return this._lottieInstance;
1239
1390
  }
1240
- async play() {
1391
+ /**
1392
+ * Play
1393
+ */ async play() {
1241
1394
  if (!this._lottieInstance) {
1242
1395
  return;
1243
1396
  }
@@ -1251,7 +1404,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1251
1404
  this.playerState = PlayerState.Playing;
1252
1405
  }
1253
1406
  }
1254
- pause() {
1407
+ /**
1408
+ * Pause
1409
+ */ pause() {
1255
1410
  if (!this._lottieInstance) {
1256
1411
  return;
1257
1412
  }
@@ -1265,7 +1420,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1265
1420
  this.playerState = PlayerState.Paused;
1266
1421
  }
1267
1422
  }
1268
- stop() {
1423
+ /**
1424
+ * Stop
1425
+ */ stop() {
1269
1426
  if (!this._lottieInstance) {
1270
1427
  return;
1271
1428
  }
@@ -1280,7 +1437,9 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1280
1437
  this.playerState = PlayerState.Stopped;
1281
1438
  }
1282
1439
  }
1283
- destroy() {
1440
+ /**
1441
+ * Destroy animation and element
1442
+ */ destroy() {
1284
1443
  if (!this._lottieInstance) {
1285
1444
  return;
1286
1445
  }
@@ -1291,16 +1450,23 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1291
1450
  this.remove();
1292
1451
  document.removeEventListener('visibilitychange', this._onVisibilityChange);
1293
1452
  }
1294
- seek(value) {
1453
+ /**
1454
+ * Seek to a given frame
1455
+ * @param { number | string } value Frame to seek to
1456
+ */ seek(value) {
1295
1457
  if (!this._lottieInstance) {
1296
1458
  return;
1297
1459
  }
1460
+ // Extract frame number from either number or percentage value
1298
1461
  const matches = value.toString().match(/^([0-9]+)(%?)$/);
1299
1462
  if (!matches) {
1300
1463
  return;
1301
1464
  }
1465
+ // Calculate and set the frame number
1302
1466
  const frame = Math.round(matches[2] === '%' ? this._lottieInstance.totalFrames * Number(matches[1]) / 100 : Number(matches[1]));
1467
+ // Set seeker to new frame number
1303
1468
  this._seeker = frame;
1469
+ // Send lottie player to the new frame
1304
1470
  if (this.playerState === PlayerState.Playing || this.playerState === PlayerState.Frozen && this._playerState.prev === PlayerState.Playing) {
1305
1471
  this._lottieInstance.goToAndPlay(frame, true);
1306
1472
  this.playerState = PlayerState.Playing;
@@ -1309,34 +1475,52 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1309
1475
  this._lottieInstance.goToAndStop(frame, true);
1310
1476
  this._lottieInstance.pause();
1311
1477
  }
1312
- snapshot() {
1313
- if (!this.shadowRoot || !this.src) {
1314
- return;
1315
- }
1316
- const svgElement = this.shadowRoot.querySelector('.animation svg'), data = svgElement instanceof Node ? new XMLSerializer().serializeToString(svgElement) : null;
1317
- if (!data) {
1318
- console.error('Could not serialize data');
1319
- return;
1478
+ /**
1479
+ * Snapshot and download the current frame as SVG
1480
+ */ snapshot(shouldDownload = true) {
1481
+ try {
1482
+ if (!this.shadowRoot || !this.src) {
1483
+ throw new Error('Unknown error');
1484
+ }
1485
+ // Get SVG element and serialize markup
1486
+ const svgElement = this.shadowRoot.querySelector('.animation svg'), data = svgElement instanceof Node ? new XMLSerializer().serializeToString(svgElement) : null;
1487
+ if (!data) {
1488
+ throw new Error('Could not serialize data');
1489
+ }
1490
+ if (shouldDownload) {
1491
+ download(data, {
1492
+ mimeType: 'image/svg+xml',
1493
+ name: `${getFilename(this.src)}-${frameOutput(this._seeker)}.svg`
1494
+ });
1495
+ }
1496
+ return data;
1497
+ } catch (err) {
1498
+ console.error(err);
1499
+ return null;
1320
1500
  }
1321
- download(data, {
1322
- mimeType: 'image/svg+xml',
1323
- name: `${getFilename(this.src)}-${frameOutput(this._seeker)}.svg`
1324
- });
1325
- return data;
1326
1501
  }
1327
- setSubframe(value) {
1502
+ /**
1503
+ * Toggles subframe, for more smooth animations
1504
+ * @param { boolean } value Whether animation uses subframe
1505
+ */ setSubframe(value) {
1328
1506
  if (!this._lottieInstance) {
1329
1507
  return;
1330
1508
  }
1331
1509
  this._lottieInstance.setSubframe(value);
1332
1510
  }
1333
- setCount(value) {
1511
+ /**
1512
+ * Dynamically set count for loops
1513
+ */ setCount(value) {
1334
1514
  if (!this._lottieInstance) {
1335
1515
  return;
1336
1516
  }
1337
1517
  this.count = value;
1338
1518
  }
1339
- _freeze() {
1519
+ /**
1520
+ * Freeze animation.
1521
+ * This internal state pauses animation and is used to differentiate between
1522
+ * user requested pauses and component instigated pauses.
1523
+ */ _freeze() {
1340
1524
  if (!this._lottieInstance) {
1341
1525
  return;
1342
1526
  }
@@ -1350,32 +1534,45 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1350
1534
  this.playerState = PlayerState.Frozen;
1351
1535
  }
1352
1536
  }
1353
- async reload() {
1537
+ /**
1538
+ * Reload animation
1539
+ */ async reload() {
1354
1540
  if (!this._lottieInstance || !this.src) {
1355
1541
  return;
1356
1542
  }
1357
1543
  this._lottieInstance.destroy();
1358
1544
  await this.load(this.src);
1359
1545
  }
1360
- setSpeed(value = 1) {
1546
+ /**
1547
+ * Set animation playback speed
1548
+ * @param { number } value Playback speed
1549
+ */ setSpeed(value = 1) {
1361
1550
  if (!this._lottieInstance) {
1362
1551
  return;
1363
1552
  }
1364
1553
  this._lottieInstance.setSpeed(value);
1365
1554
  }
1366
- setDirection(value) {
1555
+ /**
1556
+ * Animation play direction
1557
+ * @param { AnimationDirection } value Animation direction
1558
+ */ setDirection(value) {
1367
1559
  if (!this._lottieInstance) {
1368
1560
  return;
1369
1561
  }
1370
1562
  this._lottieInstance.setDirection(value);
1371
1563
  }
1372
- setLoop(value) {
1564
+ /**
1565
+ * Set loop
1566
+ * @param { boolean } value
1567
+ */ setLoop(value) {
1373
1568
  if (!this._lottieInstance) {
1374
1569
  return;
1375
1570
  }
1376
1571
  this._lottieInstance.setLoop(value);
1377
1572
  }
1378
- togglePlay() {
1573
+ /**
1574
+ * Toggle playing state
1575
+ */ togglePlay() {
1379
1576
  if (!this._lottieInstance) {
1380
1577
  return;
1381
1578
  }
@@ -1396,12 +1593,16 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1396
1593
  }
1397
1594
  return this._lottieInstance.goToAndPlay(0, true);
1398
1595
  }
1399
- toggleLoop() {
1596
+ /**
1597
+ * Toggle loop
1598
+ */ toggleLoop() {
1400
1599
  const val = !this.loop;
1401
1600
  this.loop = val;
1402
1601
  this.setLoop(val);
1403
1602
  }
1404
- toggleBoomerang() {
1603
+ /**
1604
+ * Toggle Boomerang
1605
+ */ toggleBoomerang() {
1405
1606
  const curr = this._multiAnimationSettings?.[this._currentAnimation];
1406
1607
  if (curr?.mode !== undefined) {
1407
1608
  if (curr.mode === PlayMode.Normal) {
@@ -1421,31 +1622,40 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1421
1622
  this.mode = PlayMode.Normal;
1422
1623
  this._isBounce = false;
1423
1624
  }
1424
- _toggleSettings(flag) {
1625
+ /**
1626
+ * Toggle show Settings
1627
+ */ _toggleSettings(flag) {
1425
1628
  if (flag === undefined) {
1426
1629
  this._isSettingsOpen = !this._isSettingsOpen;
1427
1630
  return;
1428
1631
  }
1429
1632
  this._isSettingsOpen = flag;
1430
1633
  }
1431
- _handleBlur() {
1634
+ /**
1635
+ * Handle blur
1636
+ */ _handleBlur() {
1432
1637
  setTimeout(()=>this._toggleSettings(false), 200);
1433
1638
  }
1434
1639
  _switchInstance(isPrevious = false) {
1640
+ // Bail early if there is not animation to play
1435
1641
  if (!this._animations[this._currentAnimation]) {
1436
1642
  return;
1437
1643
  }
1438
1644
  try {
1645
+ // Clear previous animation
1439
1646
  if (this._lottieInstance) {
1440
1647
  this._lottieInstance.destroy();
1441
1648
  }
1649
+ // Re-initialize lottie player
1442
1650
  this._lottieInstance = Lottie__namespace.default.loadAnimation({
1443
1651
  ...this._getOptions(),
1444
1652
  animationData: this._animations[this._currentAnimation]
1445
1653
  });
1654
+ // Check play mode for current animation
1446
1655
  if (this._multiAnimationSettings?.[this._currentAnimation]?.mode) {
1447
1656
  this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
1448
1657
  }
1658
+ // Remove event listeners to new Lottie instance, and add new
1449
1659
  this._removeEventListeners();
1450
1660
  this._addEventListeners();
1451
1661
  this.dispatchEvent(new CustomEvent(isPrevious ? PlayerEvents.Previous : PlayerEvents.Next));
@@ -1467,11 +1677,15 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1467
1677
  this.dispatchEvent(new CustomEvent(PlayerEvents.Error));
1468
1678
  }
1469
1679
  }
1470
- next() {
1680
+ /**
1681
+ * Skip to next animation
1682
+ */ next() {
1471
1683
  this._currentAnimation++;
1472
1684
  this._switchInstance();
1473
1685
  }
1474
- prev() {
1686
+ /**
1687
+ * Skip to previous animation
1688
+ */ prev() {
1475
1689
  this._currentAnimation--;
1476
1690
  this._switchInstance(true);
1477
1691
  }
@@ -1493,21 +1707,40 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1493
1707
  shouldDownload
1494
1708
  });
1495
1709
  }
1496
- static get styles() {
1710
+ /**
1711
+ * Return the styles for the component
1712
+ */ static get styles() {
1497
1713
  const styleSheet = new CSSStyleSheet();
1498
1714
  styleSheet.replace(css_248z);
1499
1715
  return styleSheet;
1500
1716
  }
1501
1717
  constructor(){
1502
- 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 = {
1718
+ super(), this._renderControls = renderControls, this._render = renderPlayer, /**
1719
+ * Multi-animation settings
1720
+ */ this._multiAnimationSettings = [], /**
1721
+ * @state
1722
+ * Player state
1723
+ */ this.playerState = PlayerState.Loading, /**
1724
+ * @state
1725
+ * Whether settings toolbar is open
1726
+ */ this._isSettingsOpen = false, /**
1727
+ * @state
1728
+ * Seeker
1729
+ */ this._seeker = 0, /**
1730
+ * @state
1731
+ * Which animation to show, if several
1732
+ */ 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 = {
1503
1733
  count: 0,
1504
1734
  loaded: false,
1505
1735
  prev: PlayerState.Loading,
1506
1736
  scrollTimeout: null,
1507
1737
  scrollY: 0,
1508
1738
  visible: false
1509
- }, this._handleSettingsClick = ({ target })=>{
1739
+ }, /**
1740
+ * Handle settings click event
1741
+ */ this._handleSettingsClick = ({ target })=>{
1510
1742
  this._toggleSettings();
1743
+ // Because Safari does not add focus on click, we need to add it manually, so the onblur event will fire
1511
1744
  if (target instanceof HTMLElement) {
1512
1745
  target.focus();
1513
1746
  }
@@ -1544,7 +1777,10 @@ let DotLottiePlayer = class DotLottiePlayer extends EnhancedElement {
1544
1777
  }
1545
1778
  };
1546
1779
 
1547
- globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
1780
+ /**
1781
+ * Expose DotLottiePlayer class as global variable
1782
+ * @returns { DotLottiePlayer }
1783
+ */ globalThis.dotLottiePlayer = ()=>new DotLottiePlayer();
1548
1784
  const tagName = 'dotlottie-player';
1549
1785
  if (!isServer()) {
1550
1786
  customElements.define('dotlottie-player', DotLottiePlayer);