@glissade/lottie 0.48.0-pre.1 → 0.48.0-pre.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/dist/index.js +64 -11
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -1402,7 +1402,56 @@ function sampleToLottieKeys(tr, fr, ip, op, toS) {
|
|
|
1402
1402
|
}
|
|
1403
1403
|
out.push(frame);
|
|
1404
1404
|
}
|
|
1405
|
-
return decimateLinearKeys(out);
|
|
1405
|
+
return anchorSampledSpan(decimateLinearKeys(out), f0, f1, ip, op, (frame) => toS(sampleTrack(tr, frame / fr)));
|
|
1406
|
+
}
|
|
1407
|
+
/**
|
|
1408
|
+
* Anchor the document boundaries of a densely-SAMPLED channel whose keyed span
|
|
1409
|
+
* [f0,f1] doesn't reach the document bounds [ip,op]. Lottie extrapolates a channel
|
|
1410
|
+
* by HOLDING its first key backward and its last key forward, so when the span
|
|
1411
|
+
* starts AFTER ip the first EMITTED sample holds backward across the whole leading
|
|
1412
|
+
* dormant run — and for a fade-in whose first key rounds to a frame PAST the fade
|
|
1413
|
+
* start (a fractional key time, `round(t·fr) > t·fr`), that first sample is already
|
|
1414
|
+
* non-zero (e.g. ~9%), so a "hidden" element GHOSTS at ~9% from t=0 instead of 0.
|
|
1415
|
+
* Make the true base explicit:
|
|
1416
|
+
* • f0 > ip → PREPEND a HOLD key at ip carrying `sampleAt(ip)` — the value
|
|
1417
|
+
* `sampleTrack` holds across the dormant run (0 for a dormant-at-0 fade). HELD,
|
|
1418
|
+
* not linearly ramped, so a long dormant window stays at the base value the
|
|
1419
|
+
* whole way instead of sloping up to the first sample.
|
|
1420
|
+
* • f1 < op → APPEND a key at op carrying `sampleAt(op)`. Lottie already holds
|
|
1421
|
+
* the last key forward, but a fractional last-key round-DOWN leaves the true
|
|
1422
|
+
* tail value unsampled (e.g. a fade-out whose final 0 is skipped); this pins it.
|
|
1423
|
+
* `body` is the already-decimated sampled keyframes; the boundary keys sit OUTSIDE
|
|
1424
|
+
* it, so decimation (which assumes pure linear segments) never touches them. A span
|
|
1425
|
+
* that already covers [ip,op] (the common integer-keyed case) returns `body`
|
|
1426
|
+
* unchanged — byte-identical to before this fix.
|
|
1427
|
+
*/
|
|
1428
|
+
function anchorSampledSpan(body, f0, f1, ip, op, sampleAt) {
|
|
1429
|
+
if (body.length === 0 || f0 <= ip && f1 >= op) return body;
|
|
1430
|
+
const out = body.slice();
|
|
1431
|
+
if (f1 < op) {
|
|
1432
|
+
const last = out[out.length - 1];
|
|
1433
|
+
out[out.length - 1] = {
|
|
1434
|
+
...last,
|
|
1435
|
+
o: {
|
|
1436
|
+
x: 0,
|
|
1437
|
+
y: 0
|
|
1438
|
+
},
|
|
1439
|
+
i: {
|
|
1440
|
+
x: 1,
|
|
1441
|
+
y: 1
|
|
1442
|
+
}
|
|
1443
|
+
};
|
|
1444
|
+
out.push({
|
|
1445
|
+
t: op,
|
|
1446
|
+
s: sampleAt(op)
|
|
1447
|
+
});
|
|
1448
|
+
}
|
|
1449
|
+
if (f0 > ip) out.unshift({
|
|
1450
|
+
t: ip,
|
|
1451
|
+
s: sampleAt(ip),
|
|
1452
|
+
h: 1
|
|
1453
|
+
});
|
|
1454
|
+
return out;
|
|
1406
1455
|
}
|
|
1407
1456
|
/**
|
|
1408
1457
|
* Ramer–Douglas–Peucker over linear-interpolated keyframes: keep the endpoints
|
|
@@ -1677,14 +1726,17 @@ function combineOpacity(ctx, node, tracks, accum) {
|
|
|
1677
1726
|
k: leafStatic * accum.factor * 100
|
|
1678
1727
|
};
|
|
1679
1728
|
const [f0, f1] = frameSpan(ctx, leafTrack ? [leafTrack, ...accum.tracks] : [...accum.tracks]);
|
|
1680
|
-
const
|
|
1681
|
-
|
|
1682
|
-
const t = f / ctx.fr;
|
|
1729
|
+
const sampleAt = (frame) => {
|
|
1730
|
+
const t = frame / ctx.fr;
|
|
1683
1731
|
let product = (leafTrack ? sampleTrack(leafTrack, t) : leafStatic) * accum.factor;
|
|
1684
1732
|
for (const at of accum.tracks) product *= sampleTrack(at, t);
|
|
1733
|
+
return [product * 100];
|
|
1734
|
+
};
|
|
1735
|
+
const out = [];
|
|
1736
|
+
for (let f = f0; f <= f1; f++) {
|
|
1685
1737
|
const frame = {
|
|
1686
1738
|
t: f,
|
|
1687
|
-
s:
|
|
1739
|
+
s: sampleAt(f)
|
|
1688
1740
|
};
|
|
1689
1741
|
if (f < f1) {
|
|
1690
1742
|
frame.o = {
|
|
@@ -1700,7 +1752,7 @@ function combineOpacity(ctx, node, tracks, accum) {
|
|
|
1700
1752
|
}
|
|
1701
1753
|
return {
|
|
1702
1754
|
a: 1,
|
|
1703
|
-
k: decimateLinearKeys(out)
|
|
1755
|
+
k: anchorSampledSpan(decimateLinearKeys(out), f0, f1, ctx.ip, ctx.op, sampleAt)
|
|
1704
1756
|
};
|
|
1705
1757
|
}
|
|
1706
1758
|
function scalarProp(ctx, tracks, prop, staticVal, map) {
|
|
@@ -1774,14 +1826,15 @@ function positionProp(ctx, tracks, staticPos) {
|
|
|
1774
1826
|
}
|
|
1775
1827
|
function sampleComponentVec(ctx, xt, yt, staticVal, map) {
|
|
1776
1828
|
const [f0, f1] = frameSpan(ctx, [xt, yt]);
|
|
1829
|
+
const sampleAt = (frame) => {
|
|
1830
|
+
const t = frame / ctx.fr;
|
|
1831
|
+
return map([xt ? sampleTrack(xt, t) : staticVal[0], yt ? sampleTrack(yt, t) : staticVal[1]]);
|
|
1832
|
+
};
|
|
1777
1833
|
const out = [];
|
|
1778
1834
|
for (let f = f0; f <= f1; f++) {
|
|
1779
|
-
const t = f / ctx.fr;
|
|
1780
|
-
const x = xt ? sampleTrack(xt, t) : staticVal[0];
|
|
1781
|
-
const y = yt ? sampleTrack(yt, t) : staticVal[1];
|
|
1782
1835
|
const frame = {
|
|
1783
1836
|
t: f,
|
|
1784
|
-
s:
|
|
1837
|
+
s: sampleAt(f)
|
|
1785
1838
|
};
|
|
1786
1839
|
if (f < f1) {
|
|
1787
1840
|
frame.o = {
|
|
@@ -1795,7 +1848,7 @@ function sampleComponentVec(ctx, xt, yt, staticVal, map) {
|
|
|
1795
1848
|
}
|
|
1796
1849
|
out.push(frame);
|
|
1797
1850
|
}
|
|
1798
|
-
return decimateLinearKeys(out);
|
|
1851
|
+
return anchorSampledSpan(decimateLinearKeys(out), f0, f1, ctx.ip, ctx.op, sampleAt);
|
|
1799
1852
|
}
|
|
1800
1853
|
/** Union frame span of a set of tracks (their first→last key), else [ip, op]. */
|
|
1801
1854
|
function frameSpan(ctx, tracks) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glissade/lottie",
|
|
3
|
-
"version": "0.48.0-pre.
|
|
3
|
+
"version": "0.48.0-pre.2",
|
|
4
4
|
"description": "glissade Lottie import (S1 MVP): pure .json (Lottie/bodymovin) → node specs + a v1 Timeline. Fail-fast feature audit; no DOM/Node dependencies.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"engines": {
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@glissade/core": "0.48.0-pre.
|
|
22
|
-
"@glissade/scene": "0.48.0-pre.
|
|
21
|
+
"@glissade/core": "0.48.0-pre.2",
|
|
22
|
+
"@glissade/scene": "0.48.0-pre.2"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
|
-
"@glissade/backend-skia": "0.48.0-pre.
|
|
25
|
+
"@glissade/backend-skia": "0.48.0-pre.2"
|
|
26
26
|
},
|
|
27
27
|
"repository": {
|
|
28
28
|
"type": "git",
|