@lordicon/utils-lottie 1.3.0 โ 1.4.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 +41 -0
- package/README.md +177 -8
- package/dist/icon-data.d.ts +45 -0
- package/dist/index.d.ts +4 -3
- package/dist/index.js +504 -421
- package/dist/interfaces.d.ts +2 -1
- package/dist/lottie.d.ts +20 -4
- package/dist/parsers.d.ts +24 -21
- package/dist/states.d.ts +31 -0
- package/dist/utils.d.ts +1 -1
- package/package.json +37 -18
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 1.4.0
|
|
4
|
+
|
|
5
|
+
Nothing is removed or renamed; code written for 1.3 keeps working. Some results change where
|
|
6
|
+
1.3 gave wrong ones.
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- `IconData` (with `LottieMarker`, `LottieLayer`, `LottieEffect`, `LottieAsset`) and
|
|
11
|
+
`isIconData()`: a typed Lottie file and a check for one.
|
|
12
|
+
- States: `stateType()`, `stateSegment()`, `stateRatio()`, `splitSegment()`, `stateEndFrame()`,
|
|
13
|
+
`findState()`, `defaultState()`.
|
|
14
|
+
- Colours: `defaultColors()`, `colorsByName()`, `resolveColor()`, `formatColors()`.
|
|
15
|
+
- Stroke: `hasStroke()`, `strokeName()`.
|
|
16
|
+
- An `exports` map. Only the package root can be imported, as before in practice.
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- `customizeIcon()` with a `state`:
|
|
21
|
+
- ends the file at `tm + dr + 1`, so the state's last frame plays (it stopped one frame short);
|
|
22
|
+
- keeps the params of the other markers (`morph-select:0.5` lost its ratio);
|
|
23
|
+
- changes nothing when the file has no such state (it dropped the default flag, and with
|
|
24
|
+
`'full'` left an empty icon).
|
|
25
|
+
- `customizeIcon()` with `minify`: no longer removes layers whose name holds a `:` but no
|
|
26
|
+
stroke prefix, such as a morph's `morph-select:0.5` layers or `Rectangle 2 :M`.
|
|
27
|
+
- `customizeIcon()`, `remapColors()` and `updateLottieProperties()` skip values that are not
|
|
28
|
+
colours instead of writing black.
|
|
29
|
+
- `remapColors()` matches colours whatever their case or form (`#ABC`, `#aabbcc`, `red`).
|
|
30
|
+
- `hexToRgb()` and `hexToTupleColor()` read `#rgb`; `tupleColorToHex()` clamps values outside 0โ1.
|
|
31
|
+
- `parseColors()` trims spaces and leaves out pairs that are not colours; `parseStroke()` trims
|
|
32
|
+
and ignores case.
|
|
33
|
+
- `parseColor()` returns lower-case `#rrggbb`, and black for a malformed hex.
|
|
34
|
+
- `readStates()` skips markers without a name or without frames.
|
|
35
|
+
- `extractLottieProperties()` skips effects without a name; `set()` does nothing on a missing path.
|
|
36
|
+
- Three colour names had wrong values or keys: `indianred`, `mediumpurple`, `palevioletred`.
|
|
37
|
+
|
|
38
|
+
### Deprecated
|
|
39
|
+
|
|
40
|
+
- `parseColor()`: use `resolveColor()`, which returns null for what is not a colour.
|
|
41
|
+
- `parseState()`: nothing to parse.
|
package/README.md
CHANGED
|
@@ -1,14 +1,183 @@
|
|
|
1
1
|
# Lottie Utilities
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- ๐ฆ Parse Lottie files and extract their structure.
|
|
6
|
-
- ๐๏ธ Retrieve properties for dynamic updates (colors, stroke, etc.).
|
|
7
|
-
- โ๏ธ Update Lottie files with new property values.
|
|
8
|
-
- ๐งน Remove unnecessary elements to optimize your Lottie animations.
|
|
9
|
-
|
|
10
|
-
## Installation
|
|
3
|
+
Reads and changes Lordicon icon files (Lottie JSON): their states, colours and stroke, and
|
|
4
|
+
makes customised copies of an icon. No DOM needed, so it runs in Node as well as the browser.
|
|
11
5
|
|
|
12
6
|
```bash
|
|
13
7
|
npm install @lordicon/utils-lottie
|
|
14
8
|
```
|
|
9
|
+
|
|
10
|
+
```js
|
|
11
|
+
import { customizeIcon, defaultColors, defaultState, readStates } from '@lordicon/utils-lottie';
|
|
12
|
+
|
|
13
|
+
const data = await (await fetch('/icons/share.json')).json();
|
|
14
|
+
|
|
15
|
+
defaultState(readStates(data)).name; // 'hover-pinch'
|
|
16
|
+
defaultColors(data); // { primary: '#121331' }
|
|
17
|
+
customizeIcon(data, { colors: { primary: 'red' }, stroke: 'bold' }); // a new file
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## States
|
|
21
|
+
|
|
22
|
+
An icon holds several animations, its states: an entrance (`in-reveal`), hover effects
|
|
23
|
+
(`hover-pinch`), sometimes a morph (`morph-select`) or a loop. One of them, usually a hover,
|
|
24
|
+
is the default.
|
|
25
|
+
|
|
26
|
+
```js
|
|
27
|
+
import {
|
|
28
|
+
defaultState,
|
|
29
|
+
findState,
|
|
30
|
+
readStates,
|
|
31
|
+
stateSegment,
|
|
32
|
+
stateType,
|
|
33
|
+
} from '@lordicon/utils-lottie';
|
|
34
|
+
|
|
35
|
+
const states = readStates(data); // [{ name: 'in-reveal', ... }, { name: 'hover-pinch', default: true, ... }, ...]
|
|
36
|
+
const hover = defaultState(states); // the default state
|
|
37
|
+
findState(states, 'morph'); // by name, or the first whose name starts with it
|
|
38
|
+
|
|
39
|
+
stateType(hover); // 'hover'; also 'in', 'morph', 'loop', or null
|
|
40
|
+
stateSegment(hover); // [40, 101]: its frames, for a player's segment
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
A morph goes to a second look and back. When its marker has a ratio (`morph-select:0.5`),
|
|
44
|
+
the way there and the way back are two halves of the state; without one, the whole state
|
|
45
|
+
plays forwards and then backwards.
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
import { splitSegment, stateEndFrame } from '@lordicon/utils-lottie';
|
|
49
|
+
|
|
50
|
+
const morph = findState(states, 'morph-select');
|
|
51
|
+
splitSegment(morph); // [[110, 140], [140, 171]]; null without a ratio
|
|
52
|
+
stateEndFrame(morph); // 139: where it holds its second look; the last frame without a ratio
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Colours
|
|
56
|
+
|
|
57
|
+
```js
|
|
58
|
+
import {
|
|
59
|
+
colorsByName,
|
|
60
|
+
defaultColors,
|
|
61
|
+
formatColors,
|
|
62
|
+
parseColors,
|
|
63
|
+
remapColors,
|
|
64
|
+
resolveColor,
|
|
65
|
+
} from '@lordicon/utils-lottie';
|
|
66
|
+
|
|
67
|
+
resolveColor('Tomato'); // '#ff6347'
|
|
68
|
+
resolveColor('nope'); // null
|
|
69
|
+
|
|
70
|
+
defaultColors(data); // { primary: '#121331' }
|
|
71
|
+
colorsByName(data, { '#121331': 'red' }); // { primary: '#ff0000' }
|
|
72
|
+
remapColors(data, { '#121331': 'red' }); // changes data in place, see below
|
|
73
|
+
|
|
74
|
+
parseColors('primary:red, secondary:#0f0'); // { primary: '#ff0000', secondary: '#00ff00' }
|
|
75
|
+
formatColors({ primary: 'red' }); // 'primary:#ff0000'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`colorsByName` suits a player's `colors` or the `colors` attribute; `remapColors` changes the
|
|
79
|
+
file itself. `hexToRgb`, `rgbToHex`, `hexToTupleColor` and `tupleColorToHex` convert between
|
|
80
|
+
hex, `{ r, g, b }` and Lottie's `[r, g, b]` in 0โ1.
|
|
81
|
+
|
|
82
|
+
## Stroke
|
|
83
|
+
|
|
84
|
+
```js
|
|
85
|
+
import { hasStroke, parseStroke, strokeName } from '@lordicon/utils-lottie';
|
|
86
|
+
|
|
87
|
+
hasStroke(data); // true when the width can be changed
|
|
88
|
+
parseStroke('bold'); // 3; also 'light', 'regular', 1, 2, 3
|
|
89
|
+
strokeName(3); // 'bold'
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## A customised copy
|
|
93
|
+
|
|
94
|
+
`customizeIcon(data, properties, minify?)` returns a new file with the colours, stroke and
|
|
95
|
+
default state baked in. The original is left alone.
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
import { customizeIcon } from '@lordicon/utils-lottie';
|
|
99
|
+
|
|
100
|
+
customizeIcon(data, { colors: { primary: 'red' }, stroke: 'bold', state: 'hover-pinch' });
|
|
101
|
+
customizeIcon(data, { stroke: 'bold' }, 'partial'); // drops the other widths
|
|
102
|
+
customizeIcon(data, { state: 'hover-pinch' }, 'full'); // one state, from frame 0, no expressions
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
`removeExpressions(data)` strips expressions on its own.
|
|
106
|
+
|
|
107
|
+
## Properties
|
|
108
|
+
|
|
109
|
+
The low-level way in. The colours and stroke of an icon are effects on its layers;
|
|
110
|
+
`extractLottieProperties(data)` lists them as `{ name, type, path, value }`. Pass
|
|
111
|
+
`{ lottieInstance: true }` for paths into a running `@lordicon/internal` animation instead.
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
const properties = extractLottieProperties(data);
|
|
115
|
+
const primary = properties.filter((p) => p.name === 'primary');
|
|
116
|
+
|
|
117
|
+
updateLottieProperties(data, primary, 'red'); // also { r, g, b } or [r, g, b]
|
|
118
|
+
resetLottieProperties(data, properties); // the values they had when extracted
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Reading and changing
|
|
122
|
+
|
|
123
|
+
A function that returns something leaves the data alone; one that changes the data returns
|
|
124
|
+
nothing. The data-changing ones are `updateLottieProperties`, `resetLottieProperties`,
|
|
125
|
+
`removeExpressions` and `set`. `customizeIcon` returns a new file.
|
|
126
|
+
|
|
127
|
+
The exception is `remapColors`: it changes the data **and** returns it. Pass a copy to keep
|
|
128
|
+
the original: `remapColors(structuredClone(data), colors)`.
|
|
129
|
+
|
|
130
|
+
## Types
|
|
131
|
+
|
|
132
|
+
```ts
|
|
133
|
+
import { isIconData, type IconData } from '@lordicon/utils-lottie';
|
|
134
|
+
|
|
135
|
+
const data: unknown = JSON.parse(text);
|
|
136
|
+
if (isIconData(data)) data.markers; // typed from here on
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
`IconData` describes the parts of a Lottie file these utilities read (frame rate, in and out
|
|
140
|
+
points, size, layers, markers); the rest passes through untyped. The older functions take
|
|
141
|
+
`LottieData`, which is any JSON.
|
|
142
|
+
|
|
143
|
+
## Details
|
|
144
|
+
|
|
145
|
+
**Markers.** A state is a marker in the file, named `flags:name:params`:
|
|
146
|
+
`default:morph-select:0.5` is the state `morph-select`, marked as the default, with a split
|
|
147
|
+
ratio of 0.5. Markers without a name or without frames are skipped. Two markers may share a
|
|
148
|
+
name; `findState` returns the first.
|
|
149
|
+
|
|
150
|
+
**Frames.** A marker runs from frame `tm` to frame `tm + dr`, both included: a state's last
|
|
151
|
+
keyframes sit on `tm + dr`. So a segment is `[tm, tm + dr + 1)`, with the end exclusive as
|
|
152
|
+
`setSegment()` takes it, and `customizeIcon` ends a file at `op = tm + dr + 1`. Without the
|
|
153
|
+
`+ 1` a state stops one frame short of its final pose.
|
|
154
|
+
|
|
155
|
+
**Morphs and ratios.** Not every morph has a ratio. With one, the state is two animations
|
|
156
|
+
in a row: frames up to the ratio lead to the second look, the rest lead back. Without one, the
|
|
157
|
+
state is a single animation to the second look, and the way back is the same frames played
|
|
158
|
+
backwards; `splitSegment` returns null and `stateEndFrame` the last frame. A ratio counts only
|
|
159
|
+
between 0 and 1, both excluded, and `splitSegment(state, ratio)` can impose one. Each half
|
|
160
|
+
keeps at least one frame, and a single-frame state is not split.
|
|
161
|
+
|
|
162
|
+
**Colours.** Any `#rgb` or `#rrggbb` value or CSS colour name. Colours with transparency are
|
|
163
|
+
not accepted. Values that are not colours are skipped: `parseColors` leaves the pair out,
|
|
164
|
+
`customizeIcon`, `remapColors` and `updateLottieProperties` leave the colour as it was.
|
|
165
|
+
|
|
166
|
+
**States in `customizeIcon`.** The other markers keep their params. A state the file does not
|
|
167
|
+
have changes nothing.
|
|
168
|
+
|
|
169
|
+
## Old names
|
|
170
|
+
|
|
171
|
+
`parseColor()` gives black for anything that is not a colour; use `resolveColor()`.
|
|
172
|
+
`parseState()` returns a string as it is. `get`, `set`, `has`, `isNil`, `isObjectLike` and
|
|
173
|
+
`deepClone` stay for code that uses them.
|
|
174
|
+
|
|
175
|
+
## Development
|
|
176
|
+
|
|
177
|
+
```sh
|
|
178
|
+
npm install
|
|
179
|
+
npm test
|
|
180
|
+
npm run check # types, lint, formatting
|
|
181
|
+
npm run build
|
|
182
|
+
npm start # the examples
|
|
183
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/** A marker: a named range of frames. Lordicon states are markers, `default:morph-select:0.5`. */
|
|
2
|
+
export interface LottieMarker {
|
|
3
|
+
cm: string;
|
|
4
|
+
tm: number;
|
|
5
|
+
dr: number;
|
|
6
|
+
}
|
|
7
|
+
/** An effect on a layer. Lordicon keeps an icon's colours and stroke in these. */
|
|
8
|
+
export interface LottieEffect {
|
|
9
|
+
nm: string;
|
|
10
|
+
mn: string;
|
|
11
|
+
ef?: {
|
|
12
|
+
v?: {
|
|
13
|
+
k?: unknown;
|
|
14
|
+
};
|
|
15
|
+
}[];
|
|
16
|
+
[key: string]: unknown;
|
|
17
|
+
}
|
|
18
|
+
export interface LottieLayer {
|
|
19
|
+
nm?: string;
|
|
20
|
+
ip: number;
|
|
21
|
+
op: number;
|
|
22
|
+
st: number;
|
|
23
|
+
ef?: LottieEffect[];
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}
|
|
26
|
+
export interface LottieAsset {
|
|
27
|
+
id: string;
|
|
28
|
+
layers?: LottieLayer[];
|
|
29
|
+
[key: string]: unknown;
|
|
30
|
+
}
|
|
31
|
+
/** A Lordicon icon file (Lottie JSON), as far as these utilities read it. */
|
|
32
|
+
export interface IconData {
|
|
33
|
+
v?: string;
|
|
34
|
+
fr: number;
|
|
35
|
+
ip: number;
|
|
36
|
+
op: number;
|
|
37
|
+
w: number;
|
|
38
|
+
h: number;
|
|
39
|
+
layers: LottieLayer[];
|
|
40
|
+
assets?: LottieAsset[];
|
|
41
|
+
markers?: LottieMarker[];
|
|
42
|
+
[key: string]: unknown;
|
|
43
|
+
}
|
|
44
|
+
/** True when `value` has what every Lottie file has: frame rate, in and out points, size, layers. */
|
|
45
|
+
export declare function isIconData(value: unknown): value is IconData;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { customizeIcon } from './icon';
|
|
2
2
|
export * from './interfaces';
|
|
3
|
-
export {
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
3
|
+
export { isIconData, type IconData, type LottieAsset, type LottieEffect, type LottieLayer, type LottieMarker, } from './icon-data';
|
|
4
|
+
export { colorsByName, defaultColors, extractLottieProperties, hasStroke, hexToRgb, hexToTupleColor, remapColors, removeExpressions, resetLottieProperties, rgbToHex, tupleColorToHex, updateLottieProperties, } from './lottie';
|
|
5
|
+
export { formatColors, parseColor, parseColors, parseState, parseStroke, resolveColor, strokeName, } from './parsers';
|
|
6
|
+
export { defaultState, findState, readStates, splitSegment, stateEndFrame, stateRatio, stateSegment, stateType, type Segment, type StateType, } from './states';
|
|
6
7
|
export { deepClone, get, has, isNil, isObjectLike, set } from './utils';
|