react-lottie 2.4.1 → 2.5.0
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 +17 -0
- package/README.md +33 -4
- package/dist/index.js +26 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,23 @@
|
|
|
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.5.0](https://github.com/chenqingspring/react-lottie/compare/v2.4.2...v2.5.0) (2026-11-10)
|
|
6
|
+
|
|
7
|
+
### Features
|
|
8
|
+
|
|
9
|
+
* regenerate the animation when `options.rendererSettings` changes, so `preserveAspectRatio` and the other renderer settings can be switched on a mounted component; the current frame and play/pause state are kept, and recreating an equal object does not reload anything ([#98](https://github.com/chenqingspring/react-lottie/issues/98))
|
|
10
|
+
* Storybook demo of the live `preserveAspectRatio` toggle next to the three static modes
|
|
11
|
+
|
|
12
|
+
### Documentation
|
|
13
|
+
|
|
14
|
+
* document switching `rendererSettings` on a mounted component instead of remounting the animation ([#98](https://github.com/chenqingspring/react-lottie/issues/98))
|
|
15
|
+
|
|
16
|
+
## [2.4.2](https://github.com/chenqingspring/react-lottie/compare/v2.4.1...v2.4.2) (2026-11-09)
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
|
|
20
|
+
* state that there is no npm version requirement, and why 1.x printed an `Unsupported engine` warning with npm 6 and newer ([#87](https://github.com/chenqingspring/react-lottie/issues/87))
|
|
21
|
+
|
|
5
22
|
## [2.4.1](https://github.com/chenqingspring/react-lottie/compare/v2.4.0...v2.4.1) (2026-11-08)
|
|
6
23
|
|
|
7
24
|
### Documentation
|
package/README.md
CHANGED
|
@@ -108,6 +108,12 @@ React 16.8 or newer, including React 17, React 18 and React 19. The
|
|
|
108
108
|
`--force`. The test suite runs against React 18; the component uses plain class
|
|
109
109
|
components and works with React 17 and React 19 as well.
|
|
110
110
|
|
|
111
|
+
There is no npm version requirement. 1.x declared
|
|
112
|
+
`"engines": { "npm": "^3.0.0" }`, so npm 6 and newer printed an
|
|
113
|
+
`Unsupported engine` warning on install; that field was removed before 2.0.0
|
|
114
|
+
([#87](https://github.com/chenqingspring/react-lottie/issues/87)). Install with
|
|
115
|
+
any npm version that can resolve the React peer dependency.
|
|
116
|
+
|
|
111
117
|
The component is a class, but it only uses the lifecycles React still supports
|
|
112
118
|
(`componentDidMount`, `componentDidUpdate`, `componentWillUnmount`). The
|
|
113
119
|
`componentWill*` methods that React 16.3 deprecated and React 17 stopped
|
|
@@ -532,9 +538,11 @@ Two things make a working setting look broken:
|
|
|
532
538
|
- `meet` and `slice` render identically when the container has the same aspect
|
|
533
539
|
ratio as the animation. Sizing a square animation with `height={400}
|
|
534
540
|
width={400}` leaves nothing to crop or letterbox.
|
|
535
|
-
- The value is applied when the
|
|
536
|
-
`options.rendererSettings` on a mounted component
|
|
537
|
-
|
|
541
|
+
- The value is applied when the renderer is generated. Changing
|
|
542
|
+
`options.rendererSettings` on a mounted component regenerates the animation
|
|
543
|
+
and keeps the current frame and playback state, so a live toggle works; a
|
|
544
|
+
render that recreates an object with the same values does not reload
|
|
545
|
+
anything. See [Fit or crop, live](#fit-or-crop-live).
|
|
538
546
|
|
|
539
547
|
If the `<svg>` in the inspector still lacks `preserveAspectRatio`, check what
|
|
540
548
|
you pass as `options.animationData`. An ES module namespace
|
|
@@ -544,6 +552,27 @@ scale. See [Usage](#usage).
|
|
|
544
552
|
|
|
545
553
|
The canvas renderer reads `preserveAspectRatio` too.
|
|
546
554
|
|
|
555
|
+
#### Fit or crop, live
|
|
556
|
+
|
|
557
|
+
`rendererSettings` can be switched after mount. The animation is regenerated
|
|
558
|
+
with the new settings and the current frame plus play/pause state are restored,
|
|
559
|
+
so a `meet`/`slice` toggle does not restart a half-played animation:
|
|
560
|
+
|
|
561
|
+
```jsx
|
|
562
|
+
const [mode, setMode] = useState('xMidYMid meet');
|
|
563
|
+
|
|
564
|
+
<Lottie
|
|
565
|
+
options={{ animationData, loop: true, autoplay: true, rendererSettings: { preserveAspectRatio: mode } }}
|
|
566
|
+
height={200}
|
|
567
|
+
width={400}
|
|
568
|
+
/>
|
|
569
|
+
<button onClick={() => setMode(mode === 'xMidYMid meet' ? 'xMidYMid slice' : 'xMidYMid meet')}>
|
|
570
|
+
toggle fit / crop
|
|
571
|
+
</button>
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
The Storybook story `lottie-renderer-settings` demonstrates the same toggle.
|
|
575
|
+
|
|
547
576
|
### Masks are missing in Safari
|
|
548
577
|
|
|
549
578
|
Safari resolves the `url(#…)` references that lottie-web generates for masks,
|
|
@@ -869,7 +898,7 @@ the object representing the animation settings that will be instantiated by body
|
|
|
869
898
|
>
|
|
870
899
|
>**renderer** *optional* [default: `svg`] — `svg`, `canvas` or `html`. See [Performance on iOS and low-end devices](#performance-on-ios-and-low-end-devices).
|
|
871
900
|
>
|
|
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 />`.
|
|
901
|
+
>**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 />`. Changing it regenerates the animation and keeps the current frame and playback state. See [Fit or crop an animation](#fit-or-crop-an-animation-preserveaspectratio).
|
|
873
902
|
>
|
|
874
903
|
>**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).
|
|
875
904
|
|
package/dist/index.js
CHANGED
|
@@ -9,7 +9,6 @@ var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
|
9
9
|
var _lottieWeb = _interopRequireDefault(require("lottie-web"));
|
|
10
10
|
var _colorFilters = require("./colorFilters");
|
|
11
11
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
|
|
12
|
-
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
13
12
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
14
13
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
15
14
|
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
@@ -25,6 +24,7 @@ function _setPrototypeOf(t, e) { return _setPrototypeOf = Object.setPrototypeOf
|
|
|
25
24
|
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
26
25
|
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
27
26
|
function _toPrimitive(t, e) { if ("object" != _typeof(t) || !t) return t; var r; if ("undefined" != typeof Symbol && void 0 !== (r = t[Symbol.toPrimitive])) { var i = r.call(t, e || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === e ? String : Number)(t); }
|
|
27
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
28
28
|
var segmentsAreEqual = function segmentsAreEqual(a, b) {
|
|
29
29
|
if (a === b) return true;
|
|
30
30
|
if (!Array.isArray(a) || !Array.isArray(b) || a.length !== b.length) return false;
|
|
@@ -33,6 +33,21 @@ var segmentsAreEqual = function segmentsAreEqual(a, b) {
|
|
|
33
33
|
});
|
|
34
34
|
};
|
|
35
35
|
|
|
36
|
+
/* `rendererSettings` is usually written as an object literal inside `options`,
|
|
37
|
+
so a re-render creates a new object even when nothing changed. Compare the
|
|
38
|
+
values, not the identity, to avoid reloading the animation on every render
|
|
39
|
+
while still reacting to a real change (issue #98). */
|
|
40
|
+
var rendererSettingsAreEqual = function rendererSettingsAreEqual(a, b) {
|
|
41
|
+
if (a === b) return true;
|
|
42
|
+
if (a == null || b == null) return a == null && b == null;
|
|
43
|
+
if (_typeof(a) !== 'object' || _typeof(b) !== 'object') return false;
|
|
44
|
+
var keys = Object.keys(a);
|
|
45
|
+
if (keys.length !== Object.keys(b).length) return false;
|
|
46
|
+
return keys.every(function (key) {
|
|
47
|
+
return Object.prototype.hasOwnProperty.call(b, key) && a[key] === b[key];
|
|
48
|
+
});
|
|
49
|
+
};
|
|
50
|
+
|
|
36
51
|
/* lottie-web crashes deep inside its renderer with "Cannot read property
|
|
37
52
|
'length' of undefined" when the data is not a plain animation object. Accept
|
|
38
53
|
the shapes users actually pass (a namespace import, a frozen ESM object) and
|
|
@@ -101,6 +116,7 @@ var Lottie = exports["default"] = /*#__PURE__*/function (_React$Component) {
|
|
|
101
116
|
this.animationData = animationData;
|
|
102
117
|
this.colorFilters = colorFilters;
|
|
103
118
|
this.locationHref = options.locationHref;
|
|
119
|
+
this.rendererSettings = rendererSettings;
|
|
104
120
|
var filteredAnimationData = (0, _colorFilters.applyColorFilters)(_normalizeAnimationData(animationData, options.path), colorFilters);
|
|
105
121
|
this.options = {
|
|
106
122
|
container: this.el,
|
|
@@ -159,10 +175,14 @@ var Lottie = exports["default"] = /*#__PURE__*/function (_React$Component) {
|
|
|
159
175
|
/* lottie-web bakes the base URL into each generated `url(#id)` reference,
|
|
160
176
|
so a new href only takes effect when the animation is generated again. */
|
|
161
177
|
var locationHrefChanged = this.locationHref !== this.props.options.locationHref;
|
|
178
|
+
/* `preserveAspectRatio`, `progressiveLoad` and the other renderer settings
|
|
179
|
+
are read by lottie-web when it generates the renderer, so a change has to
|
|
180
|
+
regenerate the animation too (issue #98). */
|
|
181
|
+
var rendererSettingsChanged = !rendererSettingsAreEqual(this.rendererSettings, this.props.options.rendererSettings);
|
|
162
182
|
/* The wrapper element is part of lottie-web's configuration, so a new
|
|
163
183
|
element means the animation has to be bound to the new node. */
|
|
164
184
|
var containerChanged = prevProps.as !== this.props.as;
|
|
165
|
-
if (dataChanged || pathChanged || colorFiltersChanged || locationHrefChanged || containerChanged) {
|
|
185
|
+
if (dataChanged || pathChanged || colorFiltersChanged || locationHrefChanged || rendererSettingsChanged || containerChanged) {
|
|
166
186
|
var currentFrame = this.anim ? this.anim.currentFrame : 0;
|
|
167
187
|
var wasPaused = this.anim ? this.anim.isPaused : true;
|
|
168
188
|
/* lottie-web cannot recolor a loaded animation and cannot move one to
|
|
@@ -174,10 +194,14 @@ var Lottie = exports["default"] = /*#__PURE__*/function (_React$Component) {
|
|
|
174
194
|
this.animationData = this.props.options.animationData;
|
|
175
195
|
this.colorFilters = this.props.colorFilters;
|
|
176
196
|
this.locationHref = this.props.options.locationHref;
|
|
197
|
+
this.rendererSettings = this.props.options.rendererSettings;
|
|
177
198
|
this.options = _objectSpread(_objectSpread({}, this.options), this.props.options);
|
|
178
199
|
/* `options` is caller-owned and knows nothing about the wrapper, so the
|
|
179
200
|
ref (already pointing at the newly rendered node) wins. */
|
|
180
201
|
this.options.container = this.el;
|
|
202
|
+
/* Spreading does not delete a key the caller dropped, so a removed
|
|
203
|
+
rendererSettings would otherwise keep its old value. */
|
|
204
|
+
this.options.rendererSettings = this.props.options.rendererSettings;
|
|
181
205
|
this.options.animationData = (0, _colorFilters.applyColorFilters)(_normalizeAnimationData(this.props.options.animationData, this.props.options.path), this.props.colorFilters);
|
|
182
206
|
this.setLocationHref(this.options);
|
|
183
207
|
this.anim = _lottieWeb["default"].loadAnimation(this.options);
|