@aarsteinmedia/dotlottie-player 6.0.0 → 6.0.2

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/CHANGELOG.md CHANGED
@@ -7,7 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  Changelog was only added since [3.2.3], so it's not exhaustive. [Please report any missing noteable changes to us](https://github.com/aarsteinmedia/dotlottie-player/issues), and we'll add them promptly.
9
9
 
10
- ## [6.0.0] - 22-06-2025
10
+ ## [6.0.2] - 04-07-2025
11
+
12
+ ### Changed
13
+
14
+ - Added new attribute: `dontFreezeOnBlur`. This disables default behavior where animation is frozen on window blur.
15
+
16
+ ## [6.0.1] - 22-06-2025
11
17
 
12
18
  ### Changed
13
19
 
@@ -305,6 +311,7 @@ Changelog was only added since [3.2.3], so it's not exhaustive. [Please report a
305
311
  - Removed dependencies
306
312
  - `@lit`
307
313
 
314
+ [6.0.1]: https://www.npmjs.com/package/@aarsteinmedia/dotlottie-player/v/6.0.1
308
315
  [5.3.2]: https://www.npmjs.com/package/@aarsteinmedia/dotlottie-player/v/5.3.2
309
316
  [5.2.4]: https://www.npmjs.com/package/@aarsteinmedia/dotlottie-player/v/5.2.4
310
317
  [5.2.0]: https://www.npmjs.com/package/@aarsteinmedia/dotlottie-player/v/5.2.0
package/README.md CHANGED
@@ -2,55 +2,80 @@
2
2
 
3
3
  ![Awesome Vector Animations](/.github/readmeBanner.svg)
4
4
 
5
- We proudly claim this to be the most versatile, lightweight and efficient Lottie Player Web Component available. It's compatible with server side rendering, and completely framework agnostic.
5
+ We proudly claim this to be the most versatile, lightweight, and efficient Lottie Player Web Component available. It's compatible with server-side rendering and completely framework-agnostic.
6
6
 
7
- PS: If you only need to render animations as SVG, and don't need to convert or combine animations on the fly, we've made light version: [@aarsteinmedia/dotlottie-player-light](https://www.npmjs.com/package/@aarsteinmedia/dotlottie-player-light).
7
+ If you only need to render animations as SVGs, don’t use any SVG effects like blur or drop shadow, don’t use [Expressions](https://helpx.adobe.com/after-effects/using/expression-basics.html), and dont need to convert or combine animations on the fly you can use a lighter version of this package by importing `@aarsteinmedia/dotlottie-player/light`.
8
8
 
9
9
  ## Demo
10
10
 
11
- Here is [a demo](https://www.aarstein.media/en/dotlottie-player), running on Next.js 15 using TypeScript.
11
+ Here is [a demo](https://www.aarstein.media/en/dotlottie-player), running on Next.js 15 with TypeScript.
12
12
 
13
13
  ## Installation
14
14
 
15
15
  ### In HTML
16
16
 
17
17
  - Import from CDN:
18
+ - Full version:
19
+ ```html
20
+ <script src="https://unpkg.com/@aarsteinmedia/dotlottie-player@latest/dist/unpkg-full.js"></script>
21
+ ```
22
+ - Light version:
23
+ ```html
24
+ <script src="https://unpkg.com/@aarsteinmedia/dotlottie-player@latest/dist/unpkg-light.js"></script>
25
+ ```
26
+
27
+ - Import from `node_modules`:
28
+ - Full version:
29
+ ```html
30
+ <script src="/node_modules/@aarsteinmedia/dotlottie-player/dist/unpkg-full.js"></script>
31
+ ```
32
+ - Light version:
33
+ ```html
34
+ <script src="/node_modules/@aarsteinmedia/dotlottie-player/dist/unpkg-light.js"></script>
35
+ ```
18
36
 
19
- ```xml
20
- <script src="https://unpkg.com/@aarsteinmedia/dotlottie-player@latest/dist/index.js"></script>
21
- ```
37
+ ### In JavaScript or TypeScript
22
38
 
23
- - Import from node_modules directory:
39
+ 1. Install using npm, pnpm, or yarn:
24
40
 
25
- ```xml
26
- <script src="/node_modules/@aarsteinmedia/dotlottie-player/dist/index.js"></script>
27
- ```
41
+ ```bash
42
+ pnpm add @aarsteinmedia/dotlottie-player
43
+ ```
28
44
 
29
- ### In JavaScript or TypeScript
45
+ 2. Import in your app:
30
46
 
31
- 1. Install using npm or yarn:
47
+ ```js
48
+ import '@aarsteinmedia/dotlottie-player'
49
+ ```
32
50
 
33
- ```shell
34
- npm install --save @aarsteinmedia/dotlottie-player
35
- ```
51
+ Or for the light version:
36
52
 
37
- 2. Import in your app:
53
+ ```js
54
+ import '@aarsteinmedia/dotlottie-player/light'
55
+ ```
38
56
 
39
- ```javascript
40
- import '@aarsteinmedia/dotlottie-player'
57
+ Because this is a Web Component, you're adding it to the global scope of your web app. Unlike modular components, it should only be imported once – preferably early in your app lifecycle.
58
+
59
+ If you're using TypeScript and want to import the component type, do it modularly in addition to the global import:
60
+
61
+ ```ts
62
+ import '@aarsteinmedia/dotlottie-player' // Do this once globally.
63
+ import type DotLottiePlayer from '@aarsteinmedia/dotlottie-player' // Do this per component that needs it.
41
64
  ```
42
65
 
66
+ ⚠️ Note that this pattern may provoke linter errors, such as `import/no-duplicates`.
67
+
43
68
  ## Usage
44
69
 
45
- Add the element `dotlottie-player` to your markup and point `src` to a Lottie animation of your choice.
70
+ Add the `dotlottie-player` element to your markup and point the `src` to a Lottie animation of your choice:
46
71
 
47
72
  ```html
48
73
  <dotlottie-player
49
- id="find-me"
50
74
  autoplay
51
75
  controls
52
76
  subframe
53
77
  loop
78
+ id="find-me"
54
79
  src="https://storage.googleapis.com/aarsteinmedia/am.lottie"
55
80
  style="width: 320px; margin: auto;"
56
81
  >
@@ -65,13 +90,15 @@ player?.load('https://storage.googleapis.com/aarsteinmedia/am.lottie')
65
90
  ```
66
91
 
67
92
  ### Convert to dotLottie
68
- If you have a Lottie JSON animation and want to convert it to a dotLottie – to leverage compression, combine multiple animations in one file and keep your file library tidy with a discrete file extension you can do so with the `convert()` method. This will trigger a download in the browser. If you have `controls` set to visible there's a convert button in the context menu on the right hand side.
93
+ If you have a Lottie JSON animation and want to convert it to a dotLottie file – to leverage compression, combine multiple animations, and maintain a tidy file library you can use the `convert()` method. This will trigger a browser download.
94
+
95
+ If `controls` are visible, there’s also a convert button in the context menu on the right-hand side.
69
96
 
70
97
  ### Convert to JSON
71
- If you're debugging a dotLottie animation for instance if expressions aren't working as expected, you can convert it to JSON, either by usin the `convert()` method, or if `controls` are set to visible – a button in the context menu on the right hand side.
98
+ If you're debugging a dotLottie animation (e.g., expressions arent working as expected), you can convert it to JSON either using the `convert()` method or via the convert button if `controls` are enabled.
72
99
 
73
100
  ### Combine animations
74
- If you want to combine multiple animations in one single dotLottie file you can use the `addAnimation` method. This will trigger a download in the browser. The source files can be either dotLottie or JSON, and the output file will will always be a dotLottie.
101
+ To combine multiple animations into a single dotLottie file, use the `addAnimation()` method. This also triggers a browser download. Source files can be either dotLottie or JSON, and the output will always be dotLottie:
75
102
 
76
103
  ```javascript
77
104
  const lottiePlayer = document.querySelector('#find-me')
@@ -83,9 +110,9 @@ const lottiePlayer = document.querySelector('#find-me')
83
110
  }())
84
111
  ```
85
112
 
86
- You can also use this method independent of any Lottie player on the page, as long as the script is loaded, of course.
113
+ You can also use this method without any `<dotlottie-player>` on the page. As long as the script is loaded, `dotLottiePlayer()` is available as a global method.
87
114
 
88
- ```javascript
115
+ ```js
89
116
  (async () => {
90
117
  await dotLottiePlayer().addAnimation([
91
118
  { id: 'animation_1', url: '/path/to/animation_1.lottie' },
@@ -94,20 +121,20 @@ You can also use this method independent of any Lottie player on the page, as lo
94
121
  }())
95
122
  ```
96
123
 
97
- The new file wil automatically load the first animation when initialized. You can toggle between animations with the `next()` and `prev()` methods, or you can use the navigation buttons in the controls.
124
+ The new file will automatically load the first animation when initialized. You can toggle between animations using the `next()` and `prev()` methods, or the navigation buttons in the controls.
98
125
 
99
- Control the playback of multiple animations in a single file. In the example below the first animation will play once, and then the next animation will loop:
126
+ Here’s how to control playback settings for multiple animations:
100
127
 
101
128
  ```html
102
129
  <dotlottie-player
103
- id="find-me"
104
130
  subframe
131
+ id="find-me"
105
132
  src="/path/to/combined-animations.lottie"
106
133
  >
107
134
  </dotlottie-player>
108
135
  ```
109
136
 
110
- ```javascript
137
+ ```js
111
138
  const player = document.querySelector('#find-me')
112
139
  player?.setMultiAnimationSettings(
113
140
  [
@@ -126,7 +153,7 @@ Control the playback of multiple animations in a single file. In the example bel
126
153
 
127
154
  1. Import the component in `app.component.ts`.
128
155
 
129
- ```typescript
156
+ ```ts
130
157
  import { Component } from '@angular/core'
131
158
  import '@aarsteinmedia/dotlottie-player'
132
159
 
@@ -144,7 +171,9 @@ export class AppComponent {
144
171
 
145
172
  ### React.js / Next.js
146
173
 
147
- If you've already imported the library in a parent component, you don't need to import it again in children of that component. If you want to assign the element a CSS class note that you need to use the `class` namespace, and not `className`.
174
+ Because this is a Web Component and not a React component, note that you must use the `class` attribute (not `className`) when assigning a CSS class.
175
+
176
+ If you prefer pure React logic, you may want to check out [@aarsteinmedia/dotlottie-react](https://www.npmjs.com/package/@aarsteinmedia/dotlottie-react).
148
177
 
149
178
  ```jsx
150
179
  import '@aarsteinmedia/dotlottie-player'
@@ -152,11 +181,11 @@ import '@aarsteinmedia/dotlottie-player'
152
181
  function App() {
153
182
  return (
154
183
  <dotlottie-player
155
- class="your-class-name"
156
- src="https://storage.googleapis.com/aarsteinmedia/am.lottie"
157
184
  autoplay
158
185
  controls
159
186
  loop
187
+ class="your-class-name"
188
+ src="https://storage.googleapis.com/aarsteinmedia/am.lottie"
160
189
  style={{
161
190
  width: '320px',
162
191
  margin: 'auto'
@@ -168,7 +197,7 @@ function App() {
168
197
  export default App
169
198
  ```
170
199
 
171
- If you're using TypeScript and want to assign the component a `ref`, you can do it like this:
200
+ If you're using TypeScript and want to assign a `ref`, do it like this:
172
201
 
173
202
  ```tsx
174
203
  import { useRef } from 'react'
@@ -179,8 +208,8 @@ function App() {
179
208
  const animation = useRef<DotLottiePlayer | null>(null)
180
209
  return (
181
210
  <dotlottie-player
182
- ref={animation}
183
211
  subframe
212
+ ref={animation}
184
213
  src="https://storage.googleapis.com/aarsteinmedia/am.lottie"
185
214
  />
186
215
  )
@@ -198,7 +227,7 @@ Compared to React and Angular there's a couple of extra steps, but surely nothin
198
227
  #### In Vue.js
199
228
  `vite.config.ts`:
200
229
 
201
- ```typescript
230
+ ```ts
202
231
  import { defineConfig } from 'vite'
203
232
  import vue from '@vitejs/plugin-vue'
204
233
 
@@ -218,7 +247,7 @@ export default defineConfig({
218
247
  #### In Nuxt.js
219
248
  `nuxt.config.ts`:
220
249
 
221
- ```typescript
250
+ ```ts
222
251
  export default defineNuxtConfig({
223
252
  vue: {
224
253
  compilerOptions: {
@@ -233,7 +262,7 @@ export default defineNuxtConfig({
233
262
  #### In Vue.js
234
263
  `main.ts`:
235
264
 
236
- ```typescript
265
+ ```ts
237
266
  import { createApp } from 'vue'
238
267
  import DotLottiePlayer from '@aarsteinmedia/dotlottie-player'
239
268
  import App from './App.vue'
@@ -272,11 +301,13 @@ export default defineNuxtPlugin(({ vueApp }) => {
272
301
 
273
302
  | Property / Attribute | Description | Type | Default |
274
303
  | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | ----------------- |
304
+ | `animateOnScroll` | Animate by scrolling | `boolean` | `false` |
275
305
  | `autoplay` | Play animation on load | `boolean` | `false` |
276
306
  | `background` | Background color | `string` | `undefined` |
277
307
  | `controls` | Show controls | `boolean` | `false` |
278
308
  | `count` | Number of times to loop animation | `number` | `undefined` |
279
309
  | `direction` | Direction of animation | `1` \| `-1` | `1` |
310
+ | `dontFreezeOnBlur` | Whether to freeze playback on window blur. This is default behavior, but can be disabled | `boolean` | `1` |
280
311
  | `hover` | Whether to play on mouse hover | `boolean` | `false` |
281
312
  | `loop` | Whether to loop animation | `boolean` | `false` |
282
313
  | `mode` | Play mode | `normal` \| `bounce` | `normal` |
@@ -290,8 +321,8 @@ export default defineNuxtPlugin(({ vueApp }) => {
290
321
 
291
322
  | Method | Function
292
323
  | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
293
- | `addAnimation(config: Config[]) => void` | Add animation. Triggers download of new dotLottie file. |
294
- | `convert() => void` | If the current animation is in JSON format – convert it to dotLottie. Triggers a download in the browser. |
324
+ | `addAnimation(params: AddAnimationParams) => Promise<Result>` | Add animation. Triggers download of new dotLottie file. |
325
+ | `convert(params: ConvertParams) => Promise<Result>` | If the current animation is in JSON format – convert it to dotLottie. Triggers a download in the browser. |
295
326
  | `destroy() => void` | Nullify animation and remove element from the DOM. |
296
327
  | `getLottie() => AnimationItem \| null` | Returns the lottie-web instance used in the component |
297
328
  | `load(src: string) => void` | Load animation by URL or JSON object |
package/dist/full.d.ts CHANGED
@@ -105,6 +105,8 @@ declare abstract class DotLottiePlayerBase extends PropertyCallbackElement {
105
105
  get description(): string | null;
106
106
  set direction(value: AnimationDirection);
107
107
  get direction(): AnimationDirection;
108
+ set dontFreezeOnBlur(value: boolean);
109
+ get dontFreezeOnBlur(): boolean;
108
110
  set hover(value: boolean);
109
111
  get hover(): boolean;
110
112
  set intermission(value: number);
@@ -206,7 +208,6 @@ declare abstract class DotLottiePlayerBase extends PropertyCallbackElement {
206
208
  private _getOptions;
207
209
  private _handleScroll;
208
210
  private _handleWindowBlur;
209
- private _isLottie;
210
211
  private _loopComplete;
211
212
  private _mouseEnter;
212
213
  private _mouseLeave;
package/dist/full.js CHANGED
@@ -25,7 +25,7 @@ if (isServer) {
25
25
  for(let i = 0; i < length; i++){
26
26
  const initialValue = this[observedProperties[i]], cachedValue = Symbol(observedProperties[i]);
27
27
  this[cachedValue] = initialValue;
28
- Object.defineProperty(this, observedProperties[i], {
28
+ Object.defineProperty(this, observedProperties[i] ?? '', {
29
29
  get () {
30
30
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
31
31
  return this[cachedValue];
@@ -51,8 +51,8 @@ if (isServer) {
51
51
  if (!('propertyChangedCallback' in this) || typeof this.propertyChangedCallback !== 'function') {
52
52
  continue;
53
53
  }
54
- if (arr[i] in this) {
55
- this.propertyChangedCallback(arr[i], undefined, this[arr[i]]);
54
+ if (arr[i] ?? '' in this) {
55
+ this.propertyChangedCallback(arr[i] ?? '', undefined, this[arr[i]]);
56
56
  }
57
57
  }
58
58
  }
@@ -292,6 +292,17 @@ const pauseIcon = /* HTML */ `
292
292
  }
293
293
  }
294
294
  return res;
295
+ }, isLottie = (json)=>{
296
+ const mandatory = [
297
+ 'v',
298
+ 'ip',
299
+ 'op',
300
+ 'layers',
301
+ 'fr',
302
+ 'w',
303
+ 'h'
304
+ ];
305
+ return mandatory.every((field)=>Object.hasOwn(json, field));
295
306
  }, frameOutput = (frame)=>((frame ?? 0) + 1).toString().padStart(3, '0');
296
307
 
297
308
  const notImplemented = 'Method is not implemented';
@@ -408,13 +419,22 @@ const notImplemented = 'Method is not implemented';
408
419
  return 1;
409
420
  }
410
421
  /**
422
+ * Whether to freeze animation when window loses focus.
423
+ */ set dontFreezeOnBlur(value) {
424
+ this.setAttribute('dontFreezeOnBlur', value.toString());
425
+ }
426
+ get dontFreezeOnBlur() {
427
+ const val = this.getAttribute('dontFreezeOnBlur');
428
+ return val === 'true' || val === '' || val === '1';
429
+ }
430
+ /**
411
431
  * Whether to play on mouseover.
412
432
  */ set hover(value) {
413
433
  this.setAttribute('hover', value.toString());
414
434
  }
415
435
  get hover() {
416
436
  const val = this.getAttribute('hover');
417
- return Boolean(val === 'true' || val === '' || val === '1');
437
+ return val === 'true' || val === '' || val === '1';
418
438
  }
419
439
  /**
420
440
  * Pause between loop intrations, in miliseconds.
@@ -742,16 +762,17 @@ const notImplemented = 'Method is not implemented';
742
762
  this.source = src;
743
763
  // Load the resource
744
764
  const { animations, isDotLottie, manifest } = await getAnimationData(src);
745
- if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
765
+ if (!animations || animations.some((animation)=>!isLottie(animation))) {
746
766
  throw new Error('Broken or corrupted file');
747
767
  }
748
768
  this._isBounce = this.mode === PlayMode.Bounce;
749
769
  if (this._multiAnimationSettings.length > 0 && this._multiAnimationSettings[this._currentAnimation]?.mode) {
750
- this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
770
+ this._isBounce = this._multiAnimationSettings[this._currentAnimation]?.mode === PlayMode.Bounce;
751
771
  }
752
- if (manifest?.animations.length === 1) {
753
- manifest.animations[0].autoplay = this.autoplay;
754
- manifest.animations[0].loop = this.loop;
772
+ const firstAnimation = manifest?.animations[0];
773
+ if (firstAnimation) {
774
+ firstAnimation.autoplay = this.autoplay;
775
+ firstAnimation.loop = this.loop;
755
776
  }
756
777
  this._isDotLottie = isDotLottie;
757
778
  this._animations = animations;
@@ -1136,7 +1157,7 @@ const notImplemented = 'Method is not implemented';
1136
1157
  this._intersectionObserver = new IntersectionObserver((entries)=>{
1137
1158
  const { length } = entries;
1138
1159
  for(let i = 0; i < length; i++){
1139
- if (!entries[i].isIntersecting || document.hidden) {
1160
+ if (!entries[i]?.isIntersecting || document.hidden) {
1140
1161
  if (this.playerState === PlayerState.Playing) {
1141
1162
  this._freeze();
1142
1163
  }
@@ -1278,6 +1299,9 @@ const notImplemented = 'Method is not implemented';
1278
1299
  }
1279
1300
  }
1280
1301
  _handleWindowBlur({ type }) {
1302
+ if (this.dontFreezeOnBlur) {
1303
+ return;
1304
+ }
1281
1305
  if (this.playerState === PlayerState.Playing && type === 'blur') {
1282
1306
  this._freeze();
1283
1307
  }
@@ -1285,18 +1309,6 @@ const notImplemented = 'Method is not implemented';
1285
1309
  this.play();
1286
1310
  }
1287
1311
  }
1288
- _isLottie(json) {
1289
- const mandatory = [
1290
- 'v',
1291
- 'ip',
1292
- 'op',
1293
- 'layers',
1294
- 'fr',
1295
- 'w',
1296
- 'h'
1297
- ];
1298
- return mandatory.every((field)=>Object.hasOwn(json, field));
1299
- }
1300
1312
  _loopComplete() {
1301
1313
  if (!this._lottieInstance) {
1302
1314
  return;
@@ -1380,7 +1392,7 @@ const notImplemented = 'Method is not implemented';
1380
1392
  });
1381
1393
  // Check play mode for current animation
1382
1394
  if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
1383
- this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
1395
+ this._isBounce = this._multiAnimationSettings[this._currentAnimation]?.mode === PlayMode.Bounce;
1384
1396
  }
1385
1397
  // Remove event listeners to new Lottie instance, and add new
1386
1398
  this._removeEventListeners();
package/dist/light.d.ts CHANGED
@@ -105,6 +105,8 @@ declare abstract class DotLottiePlayerBase extends PropertyCallbackElement {
105
105
  get description(): string | null;
106
106
  set direction(value: AnimationDirection);
107
107
  get direction(): AnimationDirection;
108
+ set dontFreezeOnBlur(value: boolean);
109
+ get dontFreezeOnBlur(): boolean;
108
110
  set hover(value: boolean);
109
111
  get hover(): boolean;
110
112
  set intermission(value: number);
@@ -206,7 +208,6 @@ declare abstract class DotLottiePlayerBase extends PropertyCallbackElement {
206
208
  private _getOptions;
207
209
  private _handleScroll;
208
210
  private _handleWindowBlur;
209
- private _isLottie;
210
211
  private _loopComplete;
211
212
  private _mouseEnter;
212
213
  private _mouseLeave;
package/dist/light.js CHANGED
@@ -25,7 +25,7 @@ if (isServer) {
25
25
  for(let i = 0; i < length; i++){
26
26
  const initialValue = this[observedProperties[i]], cachedValue = Symbol(observedProperties[i]);
27
27
  this[cachedValue] = initialValue;
28
- Object.defineProperty(this, observedProperties[i], {
28
+ Object.defineProperty(this, observedProperties[i] ?? '', {
29
29
  get () {
30
30
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
31
31
  return this[cachedValue];
@@ -51,8 +51,8 @@ if (isServer) {
51
51
  if (!('propertyChangedCallback' in this) || typeof this.propertyChangedCallback !== 'function') {
52
52
  continue;
53
53
  }
54
- if (arr[i] in this) {
55
- this.propertyChangedCallback(arr[i], undefined, this[arr[i]]);
54
+ if (arr[i] ?? '' in this) {
55
+ this.propertyChangedCallback(arr[i] ?? '', undefined, this[arr[i]]);
56
56
  }
57
57
  }
58
58
  }
@@ -292,6 +292,17 @@ const pauseIcon = /* HTML */ `
292
292
  }
293
293
  }
294
294
  return res;
295
+ }, isLottie = (json)=>{
296
+ const mandatory = [
297
+ 'v',
298
+ 'ip',
299
+ 'op',
300
+ 'layers',
301
+ 'fr',
302
+ 'w',
303
+ 'h'
304
+ ];
305
+ return mandatory.every((field)=>Object.hasOwn(json, field));
295
306
  }, frameOutput = (frame)=>((frame ?? 0) + 1).toString().padStart(3, '0');
296
307
 
297
308
  const notImplemented = 'Method is not implemented';
@@ -408,13 +419,22 @@ const notImplemented = 'Method is not implemented';
408
419
  return 1;
409
420
  }
410
421
  /**
422
+ * Whether to freeze animation when window loses focus.
423
+ */ set dontFreezeOnBlur(value) {
424
+ this.setAttribute('dontFreezeOnBlur', value.toString());
425
+ }
426
+ get dontFreezeOnBlur() {
427
+ const val = this.getAttribute('dontFreezeOnBlur');
428
+ return val === 'true' || val === '' || val === '1';
429
+ }
430
+ /**
411
431
  * Whether to play on mouseover.
412
432
  */ set hover(value) {
413
433
  this.setAttribute('hover', value.toString());
414
434
  }
415
435
  get hover() {
416
436
  const val = this.getAttribute('hover');
417
- return Boolean(val === 'true' || val === '' || val === '1');
437
+ return val === 'true' || val === '' || val === '1';
418
438
  }
419
439
  /**
420
440
  * Pause between loop intrations, in miliseconds.
@@ -742,16 +762,17 @@ const notImplemented = 'Method is not implemented';
742
762
  this.source = src;
743
763
  // Load the resource
744
764
  const { animations, isDotLottie, manifest } = await getAnimationData(src);
745
- if (!animations || animations.some((animation)=>!this._isLottie(animation))) {
765
+ if (!animations || animations.some((animation)=>!isLottie(animation))) {
746
766
  throw new Error('Broken or corrupted file');
747
767
  }
748
768
  this._isBounce = this.mode === PlayMode.Bounce;
749
769
  if (this._multiAnimationSettings.length > 0 && this._multiAnimationSettings[this._currentAnimation]?.mode) {
750
- this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
770
+ this._isBounce = this._multiAnimationSettings[this._currentAnimation]?.mode === PlayMode.Bounce;
751
771
  }
752
- if (manifest?.animations.length === 1) {
753
- manifest.animations[0].autoplay = this.autoplay;
754
- manifest.animations[0].loop = this.loop;
772
+ const firstAnimation = manifest?.animations[0];
773
+ if (firstAnimation) {
774
+ firstAnimation.autoplay = this.autoplay;
775
+ firstAnimation.loop = this.loop;
755
776
  }
756
777
  this._isDotLottie = isDotLottie;
757
778
  this._animations = animations;
@@ -1136,7 +1157,7 @@ const notImplemented = 'Method is not implemented';
1136
1157
  this._intersectionObserver = new IntersectionObserver((entries)=>{
1137
1158
  const { length } = entries;
1138
1159
  for(let i = 0; i < length; i++){
1139
- if (!entries[i].isIntersecting || document.hidden) {
1160
+ if (!entries[i]?.isIntersecting || document.hidden) {
1140
1161
  if (this.playerState === PlayerState.Playing) {
1141
1162
  this._freeze();
1142
1163
  }
@@ -1278,6 +1299,9 @@ const notImplemented = 'Method is not implemented';
1278
1299
  }
1279
1300
  }
1280
1301
  _handleWindowBlur({ type }) {
1302
+ if (this.dontFreezeOnBlur) {
1303
+ return;
1304
+ }
1281
1305
  if (this.playerState === PlayerState.Playing && type === 'blur') {
1282
1306
  this._freeze();
1283
1307
  }
@@ -1285,18 +1309,6 @@ const notImplemented = 'Method is not implemented';
1285
1309
  this.play();
1286
1310
  }
1287
1311
  }
1288
- _isLottie(json) {
1289
- const mandatory = [
1290
- 'v',
1291
- 'ip',
1292
- 'op',
1293
- 'layers',
1294
- 'fr',
1295
- 'w',
1296
- 'h'
1297
- ];
1298
- return mandatory.every((field)=>Object.hasOwn(json, field));
1299
- }
1300
1312
  _loopComplete() {
1301
1313
  if (!this._lottieInstance) {
1302
1314
  return;
@@ -1380,7 +1392,7 @@ const notImplemented = 'Method is not implemented';
1380
1392
  });
1381
1393
  // Check play mode for current animation
1382
1394
  if (this._multiAnimationSettings[this._currentAnimation]?.mode) {
1383
- this._isBounce = this._multiAnimationSettings[this._currentAnimation].mode === PlayMode.Bounce;
1395
+ this._isBounce = this._multiAnimationSettings[this._currentAnimation]?.mode === PlayMode.Bounce;
1384
1396
  }
1385
1397
  // Remove event listeners to new Lottie instance, and add new
1386
1398
  this._removeEventListeners();