react-lottie 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,15 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ## [2.4.1](https://github.com/chenqingspring/react-lottie/compare/v2.4.0...v2.4.1) (2026-11-08)
6
+
7
+ ### Documentation
8
+
9
+ * explain that `rendererSettings` belongs inside `options`, not on `<Lottie />`, and how `preserveAspectRatio` fits (`meet`), crops (`slice`) or stretches (`none`) an animation ([#98](https://github.com/chenqingspring/react-lottie/issues/98))
10
+ * explain why an embedded base64 image can raise `Invalid or unexpected token` from an `eval` inside a lottie expression, and how to find the offending expression ([#88](https://github.com/chenqingspring/react-lottie/issues/88))
11
+ * document taking a presentational animation out of the tab order and exposing it to screen readers with `tabIndex`, `ariaRole` and `ariaLabel` ([#130](https://github.com/chenqingspring/react-lottie/issues/130))
12
+ * add a Storybook demo of the `preserveAspectRatio` modes on a square animation in a wide container
13
+
5
14
  ## [2.4.0](https://github.com/chenqingspring/react-lottie/compare/v2.3.3...v2.4.0) (2026-11-08)
6
15
 
7
16
  ### Features
package/README.md CHANGED
@@ -363,6 +363,35 @@ keeps the animation self-contained, but it inflates the file by roughly a third
363
363
  and prevents the browser from caching the image separately, so prefer external
364
364
  images for anything large.
365
365
 
366
+ ### `Invalid or unexpected token` with embedded images
367
+
368
+ Embedded base64 images do work: an asset with `"e": 1` and a `p` value that
369
+ starts with `data:image/png;base64,` is decoded like any other image, and the
370
+ layer only has to reference it through `refId`.
371
+
372
+ The `Uncaught SyntaxError: Invalid or unexpected token` thrown from
373
+ `eval (eval at initiateExpression ...)` is not about the image. It comes from an
374
+ **expression** inside the animation. lottie-web compiles expressions with
375
+ `eval` when the animation loads. Newer After Effects versions can save an
376
+ expression in an encoded `@JSXBIN@…` form, which lottie-web cannot parse, so
377
+ the `eval` throws while the layer's effects are prepared
378
+ (`IImageElement.prepareProperties`). The same error can appear in animations
379
+ with no images at all.
380
+
381
+ Fixes, in order of preference:
382
+
383
+ - Remove the expressions in After Effects, or bake them to keyframes
384
+ (**Animation → Keyframe Assistant → Convert Expression to Keyframes**), then
385
+ export again. The animation keeps looking the same without runtime
386
+ evaluation.
387
+ - Keep the expression only if it is plain JavaScript, and make sure a Content
388
+ Security Policy is not blocking `eval` (it needs `'unsafe-eval'`). Otherwise
389
+ move that behaviour out of the animation.
390
+ - If the expression is not needed for playback, alias `lottie-web` to one of
391
+ the [light builds](#shrinking-the-lottie-web-bundle): they have no expression
392
+ engine and skip expressions instead of throwing. They skip the effect's
393
+ behaviour too, so only do this when the visual result is acceptable.
394
+
366
395
  ### Shrinking the lottie-web bundle
367
396
 
368
397
  react-lottie imports the full `lottie-web` player (299 kB minified, 611 kB
@@ -473,6 +502,48 @@ If a reduced file still drops frames, profile it: record a timeline in Safari's
473
502
  Web Inspector while the animation plays and check whether the time goes to
474
503
  lottie-web's frame update or to the browser painting and compositing the layers.
475
504
 
505
+ ### Fit or crop an animation (preserveAspectRatio)
506
+
507
+ The SVG that lottie-web generates has its own `viewBox`, and the browser scales
508
+ it to the container according to `preserveAspectRatio`. lottie-web's default is
509
+ `xMidYMid meet`, which letterboxes the animation. Use `xMidYMid slice` to fill
510
+ the container and crop the overflow instead, or `none` to stretch it.
511
+
512
+ `rendererSettings` belongs **inside `options`**, next to `animationData` or
513
+ `path`. A `rendererSettings` prop on `<Lottie />` itself is ignored, because the
514
+ component only forwards `options` to `lottie.loadAnimation()`:
515
+
516
+ ```jsx
517
+ const defaultOptions = {
518
+ animationData,
519
+ loop: true,
520
+ autoplay: true,
521
+ rendererSettings: {
522
+ preserveAspectRatio: 'xMidYMid slice',
523
+ },
524
+ };
525
+
526
+ // A wide box for a square animation, so `slice` has something to crop.
527
+ <Lottie options={defaultOptions} height={200} width={400} />
528
+ ```
529
+
530
+ Two things make a working setting look broken:
531
+
532
+ - `meet` and `slice` render identically when the container has the same aspect
533
+ ratio as the animation. Sizing a square animation with `height={400}
534
+ width={400}` leaves nothing to crop or letterbox.
535
+ - The value is applied when the animation loads. Changing
536
+ `options.rendererSettings` on a mounted component does not re-apply it;
537
+ remount the animation (or change its `key`) to pick up a new value.
538
+
539
+ If the `<svg>` in the inspector still lacks `preserveAspectRatio`, check what
540
+ you pass as `options.animationData`. An ES module namespace
541
+ (`import * as animationData`) is unwrapped for you, but any payload lottie-web
542
+ cannot read leaves it without a `viewBox`, so the attribute has nothing to
543
+ scale. See [Usage](#usage).
544
+
545
+ The canvas renderer reads `preserveAspectRatio` too.
546
+
476
547
  ### Masks are missing in Safari
477
548
 
478
549
  Safari resolves the `url(#…)` references that lottie-web generates for masks,
@@ -581,6 +652,15 @@ something else:
581
652
  <Lottie options={defaultOptions} isClickToPauseDisabled />
582
653
  ```
583
654
 
655
+ A decorative animation should also leave the tab order. Pair
656
+ `isClickToPauseDisabled` with `tabIndex={-1}` so keyboard users do not land on
657
+ an animation they cannot interact with (issue
658
+ [#130](https://github.com/chenqingspring/react-lottie/issues/130)):
659
+
660
+ ```jsx
661
+ <Lottie options={defaultOptions} isClickToPauseDisabled tabIndex={-1} />
662
+ ```
663
+
584
664
  The component has no `onClick` prop. Put your handler on a wrapper element
585
665
  instead; the click bubbles from the animation container to the wrapper:
586
666
 
@@ -652,7 +732,7 @@ The container is a `div` by default, which is not a valid child of `<p>`. Pass
652
732
 
653
733
  ```jsx
654
734
  <p>
655
- Text <Lottie as="span" options={defaultOptions} ariaRole="img" /> more text
735
+ Text <Lottie as="span" options={defaultOptions} ariaRole="img" tabIndex={-1} /> more text
656
736
  </p>
657
737
  ```
658
738
 
@@ -789,7 +869,7 @@ the object representing the animation settings that will be instantiated by body
789
869
  >
790
870
  >**renderer** *optional* [default: `svg`] — `svg`, `canvas` or `html`. See [Performance on iOS and low-end devices](#performance-on-ios-and-low-end-devices).
791
871
  >
792
- >**rendererSettings** *required*
872
+ >**rendererSettings** *optional* — settings forwarded to lottie-web's renderer, such as `preserveAspectRatio`, `progressiveLoad`, `className` and `id`. Must be inside `options`, not a prop on `<Lottie />`. Read once when the animation loads. See [Fit or crop an animation](#fit-or-crop-an-animation-preserveaspectratio).
793
873
  >
794
874
  >**locationHref** *optional* — the base URL lottie-web writes into its SVG mask, matte, gradient and filter references, applied with `setLocationHref()` before the animation is generated. Use it when Safari drops masks because of a `<base>` tag. See [Masks are missing in Safari](#masks-are-missing-in-safari).
795
875
 
@@ -892,7 +972,9 @@ Extra inline styles merged onto the container, after the `width`, `height`,
892
972
 
893
973
  **tabIndex** *optional* [default: `0`]
894
974
  Tab order of the rendered container. Pass `-1` for a purely presentational
895
- animation that should not receive keyboard focus.
975
+ animation that should not receive keyboard focus (issue
976
+ [#130](https://github.com/chenqingspring/react-lottie/issues/130)); combine it
977
+ with `isClickToPauseDisabled` as shown in [Click to pause](#click-to-pause).
896
978
 
897
979
  **as** *optional* [default: `div`]
898
980
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-lottie",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "funding": "https://opencollective.com/react-lottie",
5
5
  "description": "lottie animation view for React",
6
6
  "repository": {