morphico 0.2.0 → 0.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/README.md +77 -3
- package/dist/morphico.js +1350 -5
- package/dist/morphico.mjs +1350 -5
- package/dist/types/clip.d.ts +57 -0
- package/dist/types/face.d.ts +31 -0
- package/dist/types/index.d.ts +6 -0
- package/dist/types/morph.d.ts +5 -1
- package/dist/types/sets/faces.d.ts +25 -0
- package/dist/types/sets/shapes.d.ts +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { MorphOptions, MorphResult } from './morph.js';
|
|
2
|
+
import type { IconSet } from './types.js';
|
|
3
|
+
/** A length: a number = % (of the element's width for x and size, of its height for y), or `'40%'` / `'120px'`. */
|
|
4
|
+
export type Length = number | string;
|
|
5
|
+
/** Only a band along the shape's edge shows. */
|
|
6
|
+
export interface ClipOutline {
|
|
7
|
+
/** Width of the band in px. */
|
|
8
|
+
width: number;
|
|
9
|
+
/** Where the band sits: inside the edge (default), on it (`'centre'`) or outside it. */
|
|
10
|
+
band?: 'inside' | 'centre' | 'outside';
|
|
11
|
+
}
|
|
12
|
+
/** What can change, in `clip()` and in every `to()` / `set()`. */
|
|
13
|
+
export interface ClipChanges {
|
|
14
|
+
/** Centre of the shape, from the element's left edge (default 50 = the middle). */
|
|
15
|
+
x?: Length;
|
|
16
|
+
/** Centre of the shape, from the element's top edge (default 50 = the middle). */
|
|
17
|
+
y?: Length;
|
|
18
|
+
/** Side of the shape's square (default: the largest square that fits the element). */
|
|
19
|
+
size?: Length;
|
|
20
|
+
/** Turn in degrees, clockwise; absolute (`rotation: 360` ends one full turn from 0). */
|
|
21
|
+
rotation?: number;
|
|
22
|
+
/** Corners: 1 = the shape's own (default, the roundest) … 0 = sharp. */
|
|
23
|
+
roundness?: number;
|
|
24
|
+
/** `false` (default) = the whole shape shows; an outline = only a band along its edge (not animated). */
|
|
25
|
+
outline?: false | ClipOutline;
|
|
26
|
+
/** `true` = the other way round: the shape (or band) is a hole, the rest of the element shows (not animated). */
|
|
27
|
+
inverted?: boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface ClipOptions extends ClipChanges, MorphOptions {
|
|
30
|
+
/** The shape set (default: the built-in shapes, based on Lucide). */
|
|
31
|
+
set?: IconSet;
|
|
32
|
+
/** The shape shown first (default `'circle'`). */
|
|
33
|
+
state?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ClipChangeOptions extends ClipChanges, MorphOptions {
|
|
36
|
+
/** Called when the change ends, with the same result the promise resolves to. */
|
|
37
|
+
onEnd?: (result: MorphResult) => void;
|
|
38
|
+
}
|
|
39
|
+
export interface Clip {
|
|
40
|
+
/** The shape shown, or being morphed to. */
|
|
41
|
+
readonly state: string;
|
|
42
|
+
/**
|
|
43
|
+
* Morphs to the shape `state` and animates the given changes along (move, resize, turn, roundness), or — called with
|
|
44
|
+
* only an object — animates those changes and keeps the shape. The promise resolves when it ends; an interrupted
|
|
45
|
+
* change resolves with `interrupted: true`. Without animation when the user prefers reduced motion.
|
|
46
|
+
*/
|
|
47
|
+
to(state: string, options?: ClipChangeOptions): Promise<MorphResult>;
|
|
48
|
+
to(changes: ClipChangeOptions): Promise<MorphResult>;
|
|
49
|
+
/** Jumps (no animation), e.g. while a slider is dragged. Stops a running change (it resolves as interrupted). */
|
|
50
|
+
set(changes: ClipChanges & {
|
|
51
|
+
state?: string;
|
|
52
|
+
}): void;
|
|
53
|
+
/** Stops, removes the hidden <svg> and gives the element back its own clip-path / mask. */
|
|
54
|
+
destroy(): void;
|
|
55
|
+
}
|
|
56
|
+
/** Cuts `element` out by a morphing shape. */
|
|
57
|
+
export declare const clip: (element: HTMLElement | SVGElement, options?: ClipOptions) => Clip;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { MorphOptions, MorphResult } from './morph.js';
|
|
2
|
+
import type { FaceExpression } from './sets/faces.js';
|
|
3
|
+
export interface FaceOptions extends MorphOptions {
|
|
4
|
+
/** The expression shown first (default `'normal'`). */
|
|
5
|
+
state?: FaceExpression;
|
|
6
|
+
/** Color of the pupils (default `'white'`). Brows, eyes and mouth take the CSS `color`. */
|
|
7
|
+
pupilColor?: string;
|
|
8
|
+
/** Blink by itself every few seconds (default `true`). Off when the user prefers reduced motion. */
|
|
9
|
+
blink?: boolean;
|
|
10
|
+
/** CSS width and height of the face (default `'100%'`: it fills the element). */
|
|
11
|
+
size?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface FaceChangeOptions extends MorphOptions {
|
|
14
|
+
/** Called when the morph ends, with the same result the promise resolves to. */
|
|
15
|
+
onEnd?: (result: MorphResult) => void;
|
|
16
|
+
}
|
|
17
|
+
export interface Face {
|
|
18
|
+
/** The expression shown, or being morphed to. */
|
|
19
|
+
readonly state: FaceExpression;
|
|
20
|
+
/**
|
|
21
|
+
* Morphs to another expression. The promise resolves when the morph ends; an interrupted morph resolves with
|
|
22
|
+
* `interrupted: true`. Without animation when the user prefers reduced motion.
|
|
23
|
+
*/
|
|
24
|
+
to(state: FaceExpression, options?: FaceChangeOptions): Promise<MorphResult>;
|
|
25
|
+
/** Closes the eyes and opens them again, on top of the expression (none while asleep or with reduced motion). */
|
|
26
|
+
blink(): Promise<void>;
|
|
27
|
+
/** Stops everything and removes the face from the page. */
|
|
28
|
+
destroy(): void;
|
|
29
|
+
}
|
|
30
|
+
/** Adds a morphing face (an <svg>) to `element`. */
|
|
31
|
+
export declare const face: (element: Element, options?: FaceOptions) => Face;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,11 +1,17 @@
|
|
|
1
|
+
export { clip } from './clip.js';
|
|
1
2
|
export { easings } from './engine.js';
|
|
3
|
+
export { face } from './face.js';
|
|
2
4
|
export { icon } from './icon.js';
|
|
3
5
|
export { iconSets } from './iconSets.js';
|
|
6
|
+
export { faceExpressionNames } from './sets/faces.js';
|
|
4
7
|
export { text } from './text.js';
|
|
8
|
+
export type { Clip, ClipChangeOptions, ClipChanges, ClipOptions, ClipOutline, Length } from './clip.js';
|
|
5
9
|
export type { Easing } from './engine.js';
|
|
10
|
+
export type { Face, FaceChangeOptions, FaceOptions } from './face.js';
|
|
6
11
|
export type { ChangeOptions, Icon, IconOptions } from './icon.js';
|
|
7
12
|
export type { IconSetName } from './iconSets.js';
|
|
8
13
|
export type { EasingName, MorphOptions, MorphResult } from './morph.js';
|
|
14
|
+
export type { FaceExpression } from './sets/faces.js';
|
|
9
15
|
export type { StyleOptions } from './svg.js';
|
|
10
16
|
export type { SetOptions, Text, TextOptions, TextResult } from './text.js';
|
|
11
17
|
export type { IconSet, TextLayout } from './types.js';
|
package/dist/types/morph.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { easings } from './engine.js';
|
|
2
2
|
import type { Easing } from './engine.js';
|
|
3
|
-
import type { IconSet } from './types.js';
|
|
3
|
+
import type { IconSet, PathNumbers } from './types.js';
|
|
4
4
|
export type EasingName = keyof typeof easings;
|
|
5
5
|
export interface MorphOptions {
|
|
6
6
|
/** Length of a morph in milliseconds (default 400). */
|
|
@@ -16,7 +16,11 @@ export interface MorphResult {
|
|
|
16
16
|
}
|
|
17
17
|
/** The empty state: nothing is drawn. Shapes grow out of it and shrink into it while fading. */
|
|
18
18
|
export declare const EMPTY_STATE = " ";
|
|
19
|
+
export declare const DEFAULT_DURATION = 400;
|
|
20
|
+
export declare const shapesOf: (iconSet: IconSet) => Record<string, PathNumbers>;
|
|
19
21
|
export declare const hasState: (iconSet: IconSet, state: string) => boolean;
|
|
22
|
+
export declare const prefersReducedMotion: () => boolean;
|
|
23
|
+
export declare const clampToUnit: (value: number) => number;
|
|
20
24
|
export interface MorphingPath {
|
|
21
25
|
/** The state shown, or being morphed to. */
|
|
22
26
|
readonly state: string;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Point } from '../types.js';
|
|
2
|
+
export declare const OUTLINE_POINTS = 24;
|
|
3
|
+
export declare const PIECE_NAMES: readonly ['leftBrow', 'rightBrow', 'leftEye', 'rightEye', 'leftPupil', 'rightPupil', 'mouth'];
|
|
4
|
+
type PieceName = typeof PIECE_NAMES[number];
|
|
5
|
+
/** One expression: the outline points of every piece. */
|
|
6
|
+
export type FacePieces = Record<PieceName, Point[]>;
|
|
7
|
+
export declare const faceExpressionNames: readonly ['normal', 'smiling', 'pleading', 'wonder', 'focused', 'fright', 'angry', 'asleep', 'sad', 'surprised', 'laughing', 'tired', 'wink-left', 'wink-right', 'suspicious', 'confused', 'smug', 'irritated', 'bored', 'curious', 'empathetic', 'guilty', 'worried', 'disappointed', 'ashamed', 'embarrassed', 'yearning', 'triumphant', 'proud', 'excited', 'scornful', 'disgusted'];
|
|
8
|
+
export type FaceExpression = typeof faceExpressionNames[number];
|
|
9
|
+
/** Every expression's pieces, built on first use (nothing runs at import). */
|
|
10
|
+
export declare const faceExpressionPieces: () => Record<FaceExpression, FacePieces>;
|
|
11
|
+
export declare const interpolateFace: (from: FacePieces, to: FacePieces, progress: number) => FacePieces;
|
|
12
|
+
/** The face with its eyes partly closed: openness 1 = as drawn, 0 = shut to a flat slit (pupils gone). */
|
|
13
|
+
export declare const blinked: (face: FacePieces, openness: number) => FacePieces;
|
|
14
|
+
/** A smooth closed curve through the points: each handle points along the neighbours' chord and is a third of its own
|
|
15
|
+
* segment long (no loops where points sit close together, as at a band's round end). Empty for a hidden piece. */
|
|
16
|
+
export declare const smoothClosedPath: (points: Point[]) => string;
|
|
17
|
+
export interface FacePaths {
|
|
18
|
+
/** Brows, eyes and mouth (one colour). */
|
|
19
|
+
features: string;
|
|
20
|
+
/** Both eyes, to clip the pupils with. */
|
|
21
|
+
eyes: string;
|
|
22
|
+
pupils: string;
|
|
23
|
+
}
|
|
24
|
+
export declare const facePaths: (face: FacePieces) => FacePaths;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { IconSet, Stroke } from '../types.js';
|
|
2
|
+
/** The shapes as Lucide draws them (Lucide coordinates); the set's states are made from these. */
|
|
3
|
+
export declare const lucideShapeOutlines: Record<string, Stroke[]>;
|
|
4
|
+
/** The shape set of clip(): states `circle`, `ellipse`, `heart` … `puzzle` (see `lucideShapeOutlines`). */
|
|
5
|
+
export declare const clipShapes: IconSet;
|
package/package.json
CHANGED