morphicons 1.4.0 → 1.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/README.md +9 -2
- package/dist/dom.d.ts +3 -2
- package/dist/dom.js +4 -3
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/react-native.js +1 -1
- package/dist/react.js +1 -1
- package/dist/{spring-BTcHiHR5.js → spring-CBynweFS.js} +7 -3
- package/dist/svelte-shared.js +1 -1
- package/dist/vue.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,7 +13,14 @@
|
|
|
13
13
|
<a href="https://www.morphicons.com"><strong>morphicons.com</strong></a> — live playground
|
|
14
14
|
</p>
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="https://github.com/sponsors/guillermolg00">
|
|
18
|
+
<img src="https://img.shields.io/badge/%E2%98%95%20Buy%20me%20a%20coffee-EA4AAA" alt="Buy me a coffee — sponsor morphicons on GitHub Sponsors">
|
|
19
|
+
</a>
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
Universal morphing for stroke-based icons (Lucide, Tab
|
|
23
|
+
ler, Heroicons, Iconoir, or your own paths): **any icon morphs into any other** with spring physics. Rotations are never declared by hand — they emerge from the math (2D Procrustes + polar interpolation). Zero runtime dependencies.
|
|
17
24
|
|
|
18
25
|
```tsx
|
|
19
26
|
import { MorphIcon } from "morphicons/react";
|
|
@@ -312,7 +319,7 @@ c_k(t) = c_{A,k} + t·d_k + (σ*ᵗ·R(t·θ*) − I)·(c_{A,k} − g_A)
|
|
|
312
319
|
|
|
313
320
|
### 6. Serialization and canonical snap
|
|
314
321
|
|
|
315
|
-
In flight, each subpath is emitted as `M x y L x y …` (+ `Z` if the pair is closed↔closed; closed→open flies open, the loop opening at the cut chosen by the circular correspondence) with 2 decimals — invisible at 24px, and the frame's only allocation. On settle, the driver **snaps to the canonical `d`** of the target icon: exact fidelity at rest (real curves, not polylines), subpath count reset after duplications, and the DOM ends up identical to a static icon's. The jump is < 0.02px — imperceptible.
|
|
322
|
+
In flight, each subpath is emitted as `M x y L x y …` (+ `Z` if the pair is closed↔closed; closed→open flies open, the loop opening at the cut chosen by the circular correspondence) with 2 decimals — invisible at 24px, and the frame's only allocation. On settle, the driver **snaps to the canonical `d`** of the target icon: exact fidelity at rest (real curves, not polylines), subpath count reset after duplications, and the DOM ends up identical to a static icon's. The jump is < 0.02px — imperceptible. The canonical `d` itself is emitted with 4 decimals, and that is a correctness choice, not a size one: arc→cubic conversion goes through trig whose last ulp differs across JS engines, and SSR hydration compares the server's bytes against the browser's — quantized emission keeps them identical, where full precision leaked each engine's ulp into the markup (a Next hydration mismatch on icons with non-cardinal arcs).
|
|
316
323
|
|
|
317
324
|
### 7. The spring
|
|
318
325
|
|
package/dist/dom.d.ts
CHANGED
|
@@ -27,8 +27,9 @@ interface Morph {
|
|
|
27
27
|
destroy(): void;
|
|
28
28
|
}
|
|
29
29
|
/** Canonical `d` of an icon: the input string verbatim, or the real cubics
|
|
30
|
-
*
|
|
31
|
-
*
|
|
30
|
+
* quantized to 4 decimals (the at-rest snap; engine-stable bytes so SSR
|
|
31
|
+
* hydration matches, see fmtCanon in core/serialize). Exported because it
|
|
32
|
+
* is what a binding renders at SSR/rest before any runtime exists. */
|
|
32
33
|
declare function canonicalD(icon: IconInput): string;
|
|
33
34
|
/** Creates the morph instance over a `<path>` and paints the initial icon. */
|
|
34
35
|
declare function createMorph(el: PathEl, icon: IconInput): Morph;
|
package/dist/dom.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as buildPlan, c as cubicsToPathD, f as interpPolar, l as serialize, n as Spring, r as resampleIcon, s as iconToCubics, t as SPRING_PRESETS, u as allocOutputs } from "./spring-
|
|
1
|
+
import { a as buildPlan, c as cubicsToPathD, f as interpPolar, l as serialize, n as Spring, r as resampleIcon, s as iconToCubics, t as SPRING_PRESETS, u as allocOutputs } from "./spring-CBynweFS.js";
|
|
2
2
|
//#region src/dom/index.ts
|
|
3
3
|
const tickers = /* @__PURE__ */ new Set();
|
|
4
4
|
let rafId = 0;
|
|
@@ -41,8 +41,9 @@ function sampledOf(icon) {
|
|
|
41
41
|
return s;
|
|
42
42
|
}
|
|
43
43
|
/** Canonical `d` of an icon: the input string verbatim, or the real cubics
|
|
44
|
-
*
|
|
45
|
-
*
|
|
44
|
+
* quantized to 4 decimals (the at-rest snap; engine-stable bytes so SSR
|
|
45
|
+
* hydration matches, see fmtCanon in core/serialize). Exported because it
|
|
46
|
+
* is what a binding renders at SSR/rest before any runtime exists. */
|
|
46
47
|
function canonicalD(icon) {
|
|
47
48
|
if (typeof icon === "string") return icon;
|
|
48
49
|
let d = canon.get(icon);
|
package/dist/index.d.ts
CHANGED
|
@@ -72,7 +72,8 @@ declare function resampleIcon(input: IconInput, N?: number): Sampled[];
|
|
|
72
72
|
/** Sampled subpaths → polyline `d` attribute. `closed[k]` appends Z to
|
|
73
73
|
* subpath k (closed loops in flight); without flags everything is open. */
|
|
74
74
|
declare function serialize(subs: readonly Float64Array[], closed?: readonly boolean[]): string;
|
|
75
|
-
/** Cubic subpaths → canonical `d
|
|
75
|
+
/** Cubic subpaths → canonical `d`, quantized to 4 decimals (engine-stable
|
|
76
|
+
* bytes; see fmtCanon). */
|
|
76
77
|
declare function cubicsToPathD(paths: readonly CubicPath[]): string;
|
|
77
78
|
//#endregion
|
|
78
79
|
export { type CubicPath, type IconInput, type IconNode, type IconNodeAttrs, type MorphPlan, type PlanItem, SPRING_PRESETS, type Sampled, Spring, type SpringPreset, type ViewBox, allocOutputs, buildPlan, cubicsToPathD, fitIcon, iconToCubics, interpLinear, interpPolar, resampleIcon, resamplePath, serialize };
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as buildPlan, c as cubicsToPathD, d as interpLinear, f as interpPolar, i as resamplePath, l as serialize, n as Spring, o as fitIcon, r as resampleIcon, s as iconToCubics, t as SPRING_PRESETS, u as allocOutputs } from "./spring-
|
|
1
|
+
import { a as buildPlan, c as cubicsToPathD, d as interpLinear, f as interpPolar, i as resamplePath, l as serialize, n as Spring, o as fitIcon, r as resampleIcon, s as iconToCubics, t as SPRING_PRESETS, u as allocOutputs } from "./spring-CBynweFS.js";
|
|
2
2
|
export { SPRING_PRESETS, Spring, allocOutputs, buildPlan, cubicsToPathD, fitIcon, iconToCubics, interpLinear, interpPolar, resampleIcon, resamplePath, serialize };
|
package/dist/react-native.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-
|
|
1
|
+
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-CBynweFS.js";
|
|
2
2
|
import { canonicalD, createMorph } from "./dom.js";
|
|
3
3
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { jsx } from "react/jsx-runtime";
|
package/dist/react.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-
|
|
1
|
+
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-CBynweFS.js";
|
|
2
2
|
import { canonicalD, createMorph } from "./dom.js";
|
|
3
3
|
import { forwardRef, useCallback, useEffect, useImperativeHandle, useLayoutEffect, useRef, useState } from "react";
|
|
4
4
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -305,12 +305,16 @@ function serialize(subs, closed) {
|
|
|
305
305
|
}
|
|
306
306
|
return d;
|
|
307
307
|
}
|
|
308
|
-
|
|
308
|
+
function fmtCanon(v) {
|
|
309
|
+
return String(Math.round(v * 1e4) / 1e4);
|
|
310
|
+
}
|
|
311
|
+
/** Cubic subpaths → canonical `d`, quantized to 4 decimals (engine-stable
|
|
312
|
+
* bytes; see fmtCanon). */
|
|
309
313
|
function cubicsToPathD(paths) {
|
|
310
314
|
let d = "";
|
|
311
315
|
for (const { pts, closed } of paths) {
|
|
312
|
-
d += `M${pts[0]} ${pts[1]}`;
|
|
313
|
-
for (let i = 2; i < pts.length; i += 6) d += `C${pts[i]} ${pts[i + 1]} ${pts[i + 2]} ${pts[i + 3]} ${pts[i + 4]} ${pts[i + 5]}`;
|
|
316
|
+
d += `M${fmtCanon(pts[0])} ${fmtCanon(pts[1])}`;
|
|
317
|
+
for (let i = 2; i < pts.length; i += 6) d += `C${fmtCanon(pts[i])} ${fmtCanon(pts[i + 1])} ${fmtCanon(pts[i + 2])} ${fmtCanon(pts[i + 3])} ${fmtCanon(pts[i + 4])} ${fmtCanon(pts[i + 5])}`;
|
|
314
318
|
if (closed) d += "Z";
|
|
315
319
|
}
|
|
316
320
|
return d;
|
package/dist/svelte-shared.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-
|
|
1
|
+
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-CBynweFS.js";
|
|
2
2
|
import { canonicalD, createMorph } from "./dom.js";
|
|
3
3
|
//#region src/svelte/shared.ts
|
|
4
4
|
/** Frozen shape of the from→to pair at t, using the pure core (SSR-safe).
|
package/dist/vue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-
|
|
1
|
+
import { a as buildPlan, f as interpPolar, l as serialize, r as resampleIcon, u as allocOutputs } from "./spring-CBynweFS.js";
|
|
2
2
|
import { canonicalD, createMorph } from "./dom.js";
|
|
3
3
|
import { defineComponent, h, onBeforeUnmount, onMounted, shallowRef, watch } from "vue";
|
|
4
4
|
//#region src/vue/index.ts
|
package/package.json
CHANGED