morphicons 1.7.0 → 2.0.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/README.md +61 -428
- package/dist/MorphIcon.astro +4 -2
- package/dist/MorphIcon.svelte +19 -8
- package/dist/adapters.d.ts +12 -11
- package/dist/adapters.js +223 -23
- package/dist/{controller-CXZuwJ_M.js → controller--7SSBggk.js} +45 -11
- package/dist/{controller-Dkruvf3Y.d.ts → controller-DKm8s2ni.d.ts} +15 -6
- package/dist/dom.d.ts +2 -2
- package/dist/dom.js +292 -31
- package/dist/element.d.ts +7 -6
- package/dist/element.js +18 -5
- package/dist/index-DDNCPQ4Z.d.ts +55 -0
- package/dist/{index-DXp5b6BU.d.ts → index-DpvKR75N.d.ts} +26 -3
- package/dist/index.d.ts +12 -47
- package/dist/index.js +2 -1
- package/dist/plan-DhaDhEVq.d.ts +76 -0
- package/dist/react-native.d.ts +7 -6
- package/dist/react-native.js +65 -11
- package/dist/react.d.ts +7 -6
- package/dist/react.js +32 -7
- package/dist/region-BjECuWZR.js +60 -0
- package/dist/region.d.ts +2 -0
- package/dist/region.js +819 -0
- package/dist/{spring-CFHloqPP.js → resample-CXlaZ5ZQ.js} +56 -142
- package/dist/spring-B_P92nf6.js +95 -0
- package/dist/spring-BgZHrI2W.d.ts +33 -0
- package/dist/svelte-shared.d.ts +6 -5
- package/dist/svelte-shared.js +1 -2
- package/dist/vue.d.ts +6 -5
- package/dist/vue.js +31 -7
- package/package.json +62 -36
- package/dist/types-JAF3s76Y.d.ts +0 -60
|
@@ -1,50 +1,4 @@
|
|
|
1
1
|
import { n as iconToCubics } from "./normalize-CYnN3Npw.js";
|
|
2
|
-
//#region src/core/interpolate.ts
|
|
3
|
-
/** Preallocated output buffers for a plan (zero allocation per frame). */
|
|
4
|
-
function allocOutputs(plan) {
|
|
5
|
-
return plan.items.map(() => new Float64Array(2 * plan.n));
|
|
6
|
-
}
|
|
7
|
-
function interpPolar(plan, t, out) {
|
|
8
|
-
for (let k = 0; k < plan.items.length; k++) {
|
|
9
|
-
const it = plan.items[k];
|
|
10
|
-
const o = out[k];
|
|
11
|
-
const n = plan.n;
|
|
12
|
-
const s = Math.exp(it.lnSigma * t);
|
|
13
|
-
const ang = it.theta * t;
|
|
14
|
-
const cos = Math.cos(ang) * s;
|
|
15
|
-
const sin = Math.sin(ang) * s;
|
|
16
|
-
let cx;
|
|
17
|
-
let cy;
|
|
18
|
-
if (it.block) {
|
|
19
|
-
const [ox, oy] = it.block.off;
|
|
20
|
-
const [dx, dy] = it.block.drift;
|
|
21
|
-
cx = it.ca[0] + dx * t + (ox * cos - oy * sin - ox);
|
|
22
|
-
cy = it.ca[1] + dy * t + (ox * sin + oy * cos - oy);
|
|
23
|
-
} else {
|
|
24
|
-
cx = it.ca[0] + (it.cb[0] - it.ca[0]) * t;
|
|
25
|
-
cy = it.ca[1] + (it.cb[1] - it.ca[1]) * t;
|
|
26
|
-
}
|
|
27
|
-
for (let i = 0; i < n; i++) {
|
|
28
|
-
const px = it.aC[2 * i] + (it.bT[2 * i] - it.aC[2 * i]) * t;
|
|
29
|
-
const py = it.aC[2 * i + 1] + (it.bT[2 * i + 1] - it.aC[2 * i + 1]) * t;
|
|
30
|
-
o[2 * i] = cx + px * cos - py * sin;
|
|
31
|
-
o[2 * i + 1] = cy + px * sin + py * cos;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/** Raw coordinate lerp (same correspondence, no decomposition). */
|
|
36
|
-
function interpLinear(plan, t, out) {
|
|
37
|
-
for (let k = 0; k < plan.items.length; k++) {
|
|
38
|
-
const it = plan.items[k];
|
|
39
|
-
const o = out[k];
|
|
40
|
-
const n = plan.n;
|
|
41
|
-
for (let i = 0; i < n; i++) {
|
|
42
|
-
o[2 * i] = it.a[2 * i] + (it.bO[2 * i] - it.a[2 * i]) * t;
|
|
43
|
-
o[2 * i + 1] = it.a[2 * i + 1] + (it.bO[2 * i + 1] - it.a[2 * i + 1]) * t;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
//#endregion
|
|
48
2
|
//#region src/core/plan.ts
|
|
49
3
|
/** Weight of |ΔL| in the subpath pairing cost. */
|
|
50
4
|
const LEN_WEIGHT = .35;
|
|
@@ -136,7 +90,7 @@ function procrustes(a, b, ca, cb) {
|
|
|
136
90
|
* scoring with score = res + λ·|θ|/π. The freedom is applied to ONE cloud
|
|
137
91
|
* — the closed one (b if both are); varying both at once would be
|
|
138
92
|
* redundant. */
|
|
139
|
-
function alignPair(aPts, bPts, aClosed = false, bClosed = false) {
|
|
93
|
+
function alignPair(aPts, bPts, aClosed = false, bClosed = false, allowReverse = true, lambda = LAMBDA) {
|
|
140
94
|
const ca = centroid(aPts);
|
|
141
95
|
const cb = centroid(bPts);
|
|
142
96
|
const varyA = aClosed && !bClosed;
|
|
@@ -149,12 +103,12 @@ function alignPair(aPts, bPts, aClosed = false, bClosed = false) {
|
|
|
149
103
|
sigma: 1,
|
|
150
104
|
res: 0
|
|
151
105
|
};
|
|
152
|
-
for (let dir = 0; dir < 2; dir++) {
|
|
106
|
+
for (let dir = 0; dir < (allowReverse ? 2 : 1); dir++) {
|
|
153
107
|
const walk = dir ? reversePts(base) : base;
|
|
154
108
|
for (let off = 0; off < offs; off++) {
|
|
155
109
|
const cand = off ? rotatePts(walk, off) : walk;
|
|
156
110
|
const s = varyA ? procrustes(cand, bPts, ca, cb) : procrustes(aPts, cand, ca, cb);
|
|
157
|
-
const score = s.res +
|
|
111
|
+
const score = s.res + lambda * Math.abs(s.theta) / Math.PI;
|
|
158
112
|
if (score < bestScore) {
|
|
159
113
|
bestScore = score;
|
|
160
114
|
best = cand;
|
|
@@ -225,7 +179,7 @@ function bestPermutation(C) {
|
|
|
225
179
|
function bestSurjection(C) {
|
|
226
180
|
const B = C.length;
|
|
227
181
|
const S = C[0].length;
|
|
228
|
-
if (S ** B >
|
|
182
|
+
if (S ** B > 1e5) {
|
|
229
183
|
const f = C.map((row) => {
|
|
230
184
|
let m = 0;
|
|
231
185
|
for (let j = 1; j < row.length; j++) if (row[j] < row[m]) m = j;
|
|
@@ -317,15 +271,9 @@ function applyGlobal(items, n) {
|
|
|
317
271
|
};
|
|
318
272
|
}
|
|
319
273
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
function buildPlan(srcSubs, dstSubs) {
|
|
324
|
-
const p = srcSubs.length;
|
|
325
|
-
const q = dstSubs.length;
|
|
326
|
-
if (p === 0 || q === 0) throw new Error("morphicons: icon has no subpaths");
|
|
327
|
-
const A = srcSubs.map((s) => s.pts);
|
|
328
|
-
const B = dstSubs.map((s) => s.pts);
|
|
274
|
+
function pairUp(A, B) {
|
|
275
|
+
const p = A.length;
|
|
276
|
+
const q = B.length;
|
|
329
277
|
const pairs = [];
|
|
330
278
|
if (p === q) {
|
|
331
279
|
const perm = bestPermutation(costMatrix(A, B));
|
|
@@ -337,43 +285,56 @@ function buildPlan(srcSubs, dstSubs) {
|
|
|
337
285
|
const f = bestSurjection(costMatrix(A, B));
|
|
338
286
|
for (let i = 0; i < p; i++) pairs.push([i, f[i]]);
|
|
339
287
|
}
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
288
|
+
return pairs;
|
|
289
|
+
}
|
|
290
|
+
function makeItem(aPts, bPts, aClosed, bClosed, allowReverse, lambda) {
|
|
291
|
+
const n = aPts.length / 2;
|
|
292
|
+
const al = alignPair(aPts, bPts, aClosed, bClosed, allowReverse, lambda);
|
|
293
|
+
const a = al.a;
|
|
294
|
+
const aC = new Float64Array(2 * n);
|
|
295
|
+
const bT = new Float64Array(2 * n);
|
|
296
|
+
const bO = new Float64Array(2 * n);
|
|
297
|
+
const cos = Math.cos(-al.theta);
|
|
298
|
+
const sin = Math.sin(-al.theta);
|
|
299
|
+
for (let i = 0; i < n; i++) {
|
|
300
|
+
aC[2 * i] = a[2 * i] - al.ca[0];
|
|
301
|
+
aC[2 * i + 1] = a[2 * i + 1] - al.ca[1];
|
|
302
|
+
const bx = al.b[2 * i] - al.cb[0];
|
|
303
|
+
const by = al.b[2 * i + 1] - al.cb[1];
|
|
304
|
+
bT[2 * i] = (bx * cos - by * sin) / al.sigma;
|
|
305
|
+
bT[2 * i + 1] = (bx * sin + by * cos) / al.sigma;
|
|
306
|
+
bO[2 * i] = al.b[2 * i];
|
|
307
|
+
bO[2 * i + 1] = al.b[2 * i + 1];
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
a,
|
|
311
|
+
aC,
|
|
312
|
+
bT,
|
|
313
|
+
bO,
|
|
314
|
+
ca: al.ca,
|
|
315
|
+
cb: al.cb,
|
|
316
|
+
theta: al.theta,
|
|
317
|
+
lnSigma: Math.log(al.sigma),
|
|
318
|
+
res: al.res,
|
|
319
|
+
closed: aClosed && bClosed,
|
|
320
|
+
block: null
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
/** Builds the morph plan between two lists of sampled subpaths. The plan is
|
|
324
|
+
* cacheable and serializable; it accepts any list — including intermediate
|
|
325
|
+
* shapes (interruptions). Filled regions use buildRegionPlan (lazy chunk,
|
|
326
|
+
* src/region/plan.ts) instead. */
|
|
327
|
+
function buildPlan(srcSubs, dstSubs) {
|
|
328
|
+
const p = srcSubs.length;
|
|
329
|
+
const q = dstSubs.length;
|
|
330
|
+
if (p === 0 || q === 0) throw new Error("morphicons: icon has no subpaths");
|
|
331
|
+
const A = srcSubs.map((s) => s.pts);
|
|
332
|
+
const B = dstSubs.map((s) => s.pts);
|
|
333
|
+
const items = pairUp(A, B).map(([si, di]) => makeItem(A[si], B[di], srcSubs[si].closed, dstSubs[di].closed, true));
|
|
334
|
+
if (items.length > 1) applyGlobal(items, A[0].length / 2);
|
|
374
335
|
return {
|
|
375
336
|
items,
|
|
376
|
-
n
|
|
337
|
+
n: A[0].length / 2
|
|
377
338
|
};
|
|
378
339
|
}
|
|
379
340
|
//#endregion
|
|
@@ -573,51 +534,4 @@ function resampleIcon(input, N = 64) {
|
|
|
573
534
|
}));
|
|
574
535
|
}
|
|
575
536
|
//#endregion
|
|
576
|
-
|
|
577
|
-
var Spring = class {
|
|
578
|
-
x = 1;
|
|
579
|
-
v = 0;
|
|
580
|
-
k = 250;
|
|
581
|
-
c = 24;
|
|
582
|
-
config(k, c) {
|
|
583
|
-
this.k = k;
|
|
584
|
-
this.c = c;
|
|
585
|
-
}
|
|
586
|
-
/** Starts (or restarts mid-flight) preserving velocity. */
|
|
587
|
-
start() {
|
|
588
|
-
this.x = 0;
|
|
589
|
-
if (this.v > 14) this.v = 14;
|
|
590
|
-
if (this.v < -14) this.v = -14;
|
|
591
|
-
}
|
|
592
|
-
/** Advances dt seconds. Returns true on settle (|1−x| < 0.001 ∧ |v| < 0.02). */
|
|
593
|
-
step(dt) {
|
|
594
|
-
const steps = Math.max(1, Math.min(16, Math.ceil(dt / (1 / 240))));
|
|
595
|
-
const s = dt / steps;
|
|
596
|
-
for (let i = 0; i < steps; i++) {
|
|
597
|
-
const a = this.k * (1 - this.x) - this.c * this.v;
|
|
598
|
-
this.v += a * s;
|
|
599
|
-
this.x += this.v * s;
|
|
600
|
-
}
|
|
601
|
-
return Math.abs(1 - this.x) < .001 && Math.abs(this.v) < .02;
|
|
602
|
-
}
|
|
603
|
-
};
|
|
604
|
-
/** Spring presets (ζ = c/(2√k)) with the API's public names. */
|
|
605
|
-
const SPRING_PRESETS = {
|
|
606
|
-
/** ζ = 1.00 — critically damped, no overshoot. */
|
|
607
|
-
smooth: {
|
|
608
|
-
k: 170,
|
|
609
|
-
c: 26
|
|
610
|
-
},
|
|
611
|
-
/** ζ = 0.73 — fast, subtle overshoot. */
|
|
612
|
-
snappy: {
|
|
613
|
-
k: 420,
|
|
614
|
-
c: 30
|
|
615
|
-
},
|
|
616
|
-
/** ζ = 0.40 — playful. */
|
|
617
|
-
bouncy: {
|
|
618
|
-
k: 300,
|
|
619
|
-
c: 14
|
|
620
|
-
}
|
|
621
|
-
};
|
|
622
|
-
//#endregion
|
|
623
|
-
export { buildPlan as a, interpPolar as c, resamplePath as i, Spring as n, allocOutputs as o, resampleIcon as r, interpLinear as s, SPRING_PRESETS as t };
|
|
537
|
+
export { buildPlan as a, makeItem as c, reversePts as d, rotatePts as f, applyGlobal as i, pairUp as l, resamplePath as n, centroid as o, SURJ_MAX as r, costMatrix as s, resampleIcon as t, procrustes as u };
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
//#region src/core/interpolate.ts
|
|
2
|
+
/** Preallocated output buffers for a plan (zero allocation per frame). */
|
|
3
|
+
function allocOutputs(plan) {
|
|
4
|
+
return plan.items.map(() => new Float64Array(2 * plan.n));
|
|
5
|
+
}
|
|
6
|
+
function interpPolar(plan, t, out) {
|
|
7
|
+
for (let k = 0; k < plan.items.length; k++) {
|
|
8
|
+
const it = plan.items[k];
|
|
9
|
+
const o = out[k];
|
|
10
|
+
const n = plan.n;
|
|
11
|
+
const s = Math.exp(it.lnSigma * t);
|
|
12
|
+
const ang = it.theta * t;
|
|
13
|
+
const cos = Math.cos(ang) * s;
|
|
14
|
+
const sin = Math.sin(ang) * s;
|
|
15
|
+
let cx;
|
|
16
|
+
let cy;
|
|
17
|
+
if (it.block) {
|
|
18
|
+
const [ox, oy] = it.block.off;
|
|
19
|
+
const [dx, dy] = it.block.drift;
|
|
20
|
+
cx = it.ca[0] + dx * t + (ox * cos - oy * sin - ox);
|
|
21
|
+
cy = it.ca[1] + dy * t + (ox * sin + oy * cos - oy);
|
|
22
|
+
} else {
|
|
23
|
+
cx = it.ca[0] + (it.cb[0] - it.ca[0]) * t;
|
|
24
|
+
cy = it.ca[1] + (it.cb[1] - it.ca[1]) * t;
|
|
25
|
+
}
|
|
26
|
+
const m = it.half === void 0 ? t : Math.min(1, Math.max(0, 2 * t - it.half));
|
|
27
|
+
for (let i = 0; i < n; i++) {
|
|
28
|
+
const px = it.aC[2 * i] + (it.bT[2 * i] - it.aC[2 * i]) * m;
|
|
29
|
+
const py = it.aC[2 * i + 1] + (it.bT[2 * i + 1] - it.aC[2 * i + 1]) * m;
|
|
30
|
+
o[2 * i] = cx + px * cos - py * sin;
|
|
31
|
+
o[2 * i + 1] = cy + px * sin + py * cos;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Raw coordinate lerp (same correspondence, no decomposition). */
|
|
36
|
+
function interpLinear(plan, t, out) {
|
|
37
|
+
for (let k = 0; k < plan.items.length; k++) {
|
|
38
|
+
const it = plan.items[k];
|
|
39
|
+
const o = out[k];
|
|
40
|
+
const n = plan.n;
|
|
41
|
+
for (let i = 0; i < n; i++) {
|
|
42
|
+
o[2 * i] = it.a[2 * i] + (it.bO[2 * i] - it.a[2 * i]) * t;
|
|
43
|
+
o[2 * i + 1] = it.a[2 * i + 1] + (it.bO[2 * i + 1] - it.a[2 * i + 1]) * t;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/core/spring.ts
|
|
49
|
+
var Spring = class {
|
|
50
|
+
x = 1;
|
|
51
|
+
v = 0;
|
|
52
|
+
k = 250;
|
|
53
|
+
c = 24;
|
|
54
|
+
config(k, c) {
|
|
55
|
+
this.k = k;
|
|
56
|
+
this.c = c;
|
|
57
|
+
}
|
|
58
|
+
/** Starts (or restarts mid-flight) preserving velocity. */
|
|
59
|
+
start() {
|
|
60
|
+
this.x = 0;
|
|
61
|
+
if (this.v > 14) this.v = 14;
|
|
62
|
+
if (this.v < -14) this.v = -14;
|
|
63
|
+
}
|
|
64
|
+
/** Advances dt seconds. Returns true on settle (|1−x| < 0.001 ∧ |v| < 0.02). */
|
|
65
|
+
step(dt) {
|
|
66
|
+
const steps = Math.max(1, Math.min(16, Math.ceil(dt / (1 / 240))));
|
|
67
|
+
const s = dt / steps;
|
|
68
|
+
for (let i = 0; i < steps; i++) {
|
|
69
|
+
const a = this.k * (1 - this.x) - this.c * this.v;
|
|
70
|
+
this.v += a * s;
|
|
71
|
+
this.x += this.v * s;
|
|
72
|
+
}
|
|
73
|
+
return Math.abs(1 - this.x) < .001 && Math.abs(this.v) < .02;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
/** Spring presets (ζ = c/(2√k)) with the API's public names. */
|
|
77
|
+
const SPRING_PRESETS = {
|
|
78
|
+
/** ζ = 1.00 — critically damped, no overshoot. */
|
|
79
|
+
smooth: {
|
|
80
|
+
k: 170,
|
|
81
|
+
c: 26
|
|
82
|
+
},
|
|
83
|
+
/** ζ = 0.73 — fast, subtle overshoot. */
|
|
84
|
+
snappy: {
|
|
85
|
+
k: 420,
|
|
86
|
+
c: 30
|
|
87
|
+
},
|
|
88
|
+
/** ζ = 0.40 — playful. */
|
|
89
|
+
bouncy: {
|
|
90
|
+
k: 300,
|
|
91
|
+
c: 14
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
//#endregion
|
|
95
|
+
export { interpPolar as a, interpLinear as i, Spring as n, allocOutputs as r, SPRING_PRESETS as t };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/core/spring.d.ts
|
|
2
|
+
declare class Spring {
|
|
3
|
+
x: number;
|
|
4
|
+
v: number;
|
|
5
|
+
k: number;
|
|
6
|
+
c: number;
|
|
7
|
+
config(k: number, c: number): void;
|
|
8
|
+
/** Starts (or restarts mid-flight) preserving velocity. */
|
|
9
|
+
start(): void;
|
|
10
|
+
/** Advances dt seconds. Returns true on settle (|1−x| < 0.001 ∧ |v| < 0.02). */
|
|
11
|
+
step(dt: number): boolean;
|
|
12
|
+
}
|
|
13
|
+
/** Spring presets (ζ = c/(2√k)) with the API's public names. */
|
|
14
|
+
declare const SPRING_PRESETS: {
|
|
15
|
+
/** ζ = 1.00 — critically damped, no overshoot. */
|
|
16
|
+
readonly smooth: {
|
|
17
|
+
readonly k: 170;
|
|
18
|
+
readonly c: 26;
|
|
19
|
+
};
|
|
20
|
+
/** ζ = 0.73 — fast, subtle overshoot. */
|
|
21
|
+
readonly snappy: {
|
|
22
|
+
readonly k: 420;
|
|
23
|
+
readonly c: 30;
|
|
24
|
+
};
|
|
25
|
+
/** ζ = 0.40 — playful. */
|
|
26
|
+
readonly bouncy: {
|
|
27
|
+
readonly k: 300;
|
|
28
|
+
readonly c: 14;
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
type SpringPreset = keyof typeof SPRING_PRESETS;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { Spring as n, SpringPreset as r, SPRING_PRESETS as t };
|
package/dist/svelte-shared.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { a as IconInput, c as Sampled, o as IconNode } from "./plan-DhaDhEVq.js";
|
|
2
|
+
import { r as SpringPreset } from "./spring-BgZHrI2W.js";
|
|
3
|
+
import { a as ReducedMotionMode, i as PathEl, n as Morph, r as MorphOptions } from "./index-DpvKR75N.js";
|
|
4
|
+
import { i as createController, n as computeInitialD, r as computeInitialPaint, t as MorphHandle } from "./controller-DKm8s2ni.js";
|
|
4
5
|
import { SVGAttributes } from "svelte/elements";
|
|
5
6
|
//#region src/svelte/shared.d.ts
|
|
6
7
|
/** Rest props fall through to the `<svg>` fully typed (class, style, data-*,
|
|
7
8
|
* events, ARIA…) via svelte/elements, like lucide-svelte — typos in an SVG
|
|
8
9
|
* attr fail the build. `from`/`to` are omitted because the SMIL animation
|
|
9
10
|
* attributes of the same name collide with the controlled-mode pair. */
|
|
10
|
-
interface MorphIconProps extends Omit<SVGAttributes<SVGSVGElement>, "from" | "to"> {
|
|
11
|
+
export interface MorphIconProps extends Omit<SVGAttributes<SVGSVGElement>, "from" | "to"> {
|
|
11
12
|
/** Uncontrolled mode: the current icon; changing the prop animates. */
|
|
12
13
|
icon?: IconInput;
|
|
13
14
|
/** Controlled mode: source endpoint of the pair. */
|
|
@@ -31,4 +32,4 @@ interface MorphIconProps extends Omit<SVGAttributes<SVGSVGElement>, "from" | "to
|
|
|
31
32
|
label?: string;
|
|
32
33
|
}
|
|
33
34
|
//#endregion
|
|
34
|
-
export { type IconInput, type IconNode, type Morph, type MorphHandle,
|
|
35
|
+
export { type IconInput, type IconNode, type Morph, type MorphHandle, type MorphOptions, type PathEl, type ReducedMotionMode, type Sampled, type SpringPreset, computeInitialD, computeInitialPaint, createController };
|
package/dist/svelte-shared.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
export { computeInitialD, createController };
|
|
1
|
+
export { t as computeInitialD, n as computeInitialPaint, r as createController } from "./controller--7SSBggk.js";
|
package/dist/vue.d.ts
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
import {
|
|
1
|
+
import { a as IconInput, c as Sampled, o as IconNode } from "./plan-DhaDhEVq.js";
|
|
2
|
+
import { r as SpringPreset } from "./spring-BgZHrI2W.js";
|
|
3
|
+
import { a as ReducedMotionMode, i as PathEl, n as Morph, r as MorphOptions } from "./index-DpvKR75N.js";
|
|
3
4
|
import { PropType } from "vue";
|
|
4
5
|
//#region src/vue/index.d.ts
|
|
5
6
|
/** Imperative surface exposed on the component instance (template ref). */
|
|
6
|
-
interface MorphHandle {
|
|
7
|
+
export interface MorphHandle {
|
|
7
8
|
morphTo(icon: IconInput, spring?: SpringPreset | MorphOptions): void;
|
|
8
9
|
set(icon: IconInput): void;
|
|
9
10
|
}
|
|
10
|
-
declare const MorphIcon: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
11
|
+
export declare const MorphIcon: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
11
12
|
/** Uncontrolled mode: the current icon; changing the prop animates. */
|
|
12
13
|
icon: {
|
|
13
14
|
type: PropType<IconInput>;
|
|
@@ -133,4 +134,4 @@ declare const MorphIcon: import("vue").DefineComponent<import("vue").ExtractProp
|
|
|
133
134
|
label: string;
|
|
134
135
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
135
136
|
//#endregion
|
|
136
|
-
export {
|
|
137
|
+
export type { IconInput, IconNode, Morph, MorphOptions, PathEl, ReducedMotionMode, Sampled, SpringPreset };
|
package/dist/vue.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { a as
|
|
1
|
+
import { a as interpPolar, r as allocOutputs } from "./spring-B_P92nf6.js";
|
|
2
2
|
import { i as serialize } from "./normalize-CYnN3Npw.js";
|
|
3
|
-
import {
|
|
3
|
+
import { a as buildPlan, t as resampleIcon } from "./resample-CXlaZ5ZQ.js";
|
|
4
|
+
import { canonicalD, createMorph, restAttrs } from "./dom.js";
|
|
5
|
+
import { i as frozenEnd } from "./controller--7SSBggk.js";
|
|
4
6
|
import { defineComponent, h, onBeforeUnmount, onMounted, shallowRef, watch } from "vue";
|
|
5
7
|
//#region src/vue/index.ts
|
|
6
8
|
/** Frozen shape of the from→to pair at t, using the pure core (SSR-safe).
|
|
7
9
|
* At exact endpoints returns the canonical `d` (real curves, not polyline). */
|
|
8
10
|
function frozenD(from, to, t) {
|
|
9
|
-
|
|
10
|
-
if (
|
|
11
|
+
const end = frozenEnd(from, to, t);
|
|
12
|
+
if (end !== null) return canonicalD(end);
|
|
11
13
|
const plan = buildPlan(resampleIcon(from), resampleIcon(to));
|
|
12
14
|
const out = allocOutputs(plan);
|
|
13
15
|
interpPolar(plan, t, out);
|
|
@@ -78,11 +80,20 @@ const MorphIcon = defineComponent({
|
|
|
78
80
|
const first = icon ?? from ?? to;
|
|
79
81
|
return first !== void 0 ? canonicalD(first) : "";
|
|
80
82
|
})();
|
|
83
|
+
const initialPaint = (() => {
|
|
84
|
+
const { icon, from, to, progress } = props;
|
|
85
|
+
if (from !== void 0 && to !== void 0) {
|
|
86
|
+
const t = progress ?? 0;
|
|
87
|
+
return restAttrs(frozenEnd(from, to, t) ?? (t < .5 ? from : to));
|
|
88
|
+
}
|
|
89
|
+
return restAttrs(icon ?? from ?? to);
|
|
90
|
+
})();
|
|
81
91
|
const pathEl = shallowRef(null);
|
|
82
92
|
let morph = null;
|
|
83
93
|
let dead = false;
|
|
84
94
|
let based = false;
|
|
85
95
|
let pair = null;
|
|
96
|
+
const gridSw = () => Number(props.absoluteStrokeWidth ? Number(props.strokeWidth) * 24 / Number(props.size) : props.strokeWidth);
|
|
86
97
|
let prevIcon = props.icon;
|
|
87
98
|
let prevControlled = props.from !== void 0 && props.to !== void 0;
|
|
88
99
|
/** Driver birth, lazy included (#1 of the lifecycle contract): an
|
|
@@ -92,7 +103,10 @@ const MorphIcon = defineComponent({
|
|
|
92
103
|
if (morph) return morph;
|
|
93
104
|
const el = pathEl.value;
|
|
94
105
|
if (dead || !el) return null;
|
|
95
|
-
morph = createMorph(el, birth, {
|
|
106
|
+
morph = createMorph(el, birth, {
|
|
107
|
+
reducedMotion: props.reducedMotion,
|
|
108
|
+
strokeWidth: gridSw()
|
|
109
|
+
});
|
|
96
110
|
return morph;
|
|
97
111
|
};
|
|
98
112
|
onMounted(() => {
|
|
@@ -101,7 +115,10 @@ const MorphIcon = defineComponent({
|
|
|
101
115
|
const controlled = from !== void 0 && to !== void 0;
|
|
102
116
|
const initialIcon = icon ?? from ?? to;
|
|
103
117
|
if (!el || initialIcon === void 0) return;
|
|
104
|
-
const m = createMorph(el, controlled ? from : initialIcon, {
|
|
118
|
+
const m = createMorph(el, controlled ? from : initialIcon, {
|
|
119
|
+
reducedMotion: props.reducedMotion,
|
|
120
|
+
strokeWidth: gridSw()
|
|
121
|
+
});
|
|
105
122
|
morph = m;
|
|
106
123
|
if (controlled) {
|
|
107
124
|
pair = [from, to];
|
|
@@ -124,6 +141,9 @@ const MorphIcon = defineComponent({
|
|
|
124
141
|
watch(() => props.reducedMotion, (v) => {
|
|
125
142
|
if (morph) morph.reducedMotion = v;
|
|
126
143
|
});
|
|
144
|
+
watch(gridSw, (v) => {
|
|
145
|
+
if (morph) morph.strokeWidth = v;
|
|
146
|
+
});
|
|
127
147
|
watch(() => [
|
|
128
148
|
props.icon,
|
|
129
149
|
props.from,
|
|
@@ -141,6 +161,7 @@ const MorphIcon = defineComponent({
|
|
|
141
161
|
based = false;
|
|
142
162
|
if (morph) {
|
|
143
163
|
morph.reducedMotion = props.reducedMotion;
|
|
164
|
+
morph.strokeWidth = gridSw();
|
|
144
165
|
morph.morphTo(icon, props.spring);
|
|
145
166
|
} else ensure(icon);
|
|
146
167
|
});
|
|
@@ -153,6 +174,7 @@ const MorphIcon = defineComponent({
|
|
|
153
174
|
if (from === void 0 || to === void 0) return;
|
|
154
175
|
const m = morph ?? ensure(from);
|
|
155
176
|
if (!m) return;
|
|
177
|
+
m.strokeWidth = gridSw();
|
|
156
178
|
const t = progress ?? 0;
|
|
157
179
|
if (!pair || pair[0] !== from || pair[1] !== to) {
|
|
158
180
|
pair = [from, to];
|
|
@@ -195,6 +217,7 @@ const MorphIcon = defineComponent({
|
|
|
195
217
|
viewBox: "0 0 24 24",
|
|
196
218
|
fill: "none",
|
|
197
219
|
stroke: props.color,
|
|
220
|
+
color: props.color,
|
|
198
221
|
"stroke-width": sw,
|
|
199
222
|
"stroke-linecap": "round",
|
|
200
223
|
"stroke-linejoin": "round",
|
|
@@ -202,7 +225,8 @@ const MorphIcon = defineComponent({
|
|
|
202
225
|
"aria-hidden": props.label ? void 0 : "true"
|
|
203
226
|
}, [props.label ? h("title", props.label) : null, h("path", {
|
|
204
227
|
ref: pathEl,
|
|
205
|
-
d: initialD
|
|
228
|
+
d: initialD,
|
|
229
|
+
...initialPaint
|
|
206
230
|
})]);
|
|
207
231
|
};
|
|
208
232
|
}
|