# Morph: API reference

> Every function and type the package exports, entry by entry: the core, React and the DOM.

Source: https://cesarvenzac.com/morph/docs/api

Three entries: the core, which runs anywhere, `@cesarvenzac/morph/react` and `@cesarvenzac/morph/dom`. The core touches neither React nor the DOM, its types included.

## The core

### morph(from, to, options?)

A morph between two sources. `options` is a way, `"soft"` (the default), `"even"`, `"index"` or `Steps`, or `{ way?, extra? }`.

```typescript
function morph(from: Source, to: Source, options?: Method | Steps | Options): Morph;

type Morph = {
  slots: number; // parts in every frame, some empty at the ends
  viewBox: Box; // the canvas every frame is drawn on
  at(t: number): Part[]; // the frame at t, 0 to 1
  shapes(t: number): Shape[]; // the same, as anchors and handles
  points(t: number): Vec[][]; // each part's outline points
};
```

### svg(markup)

A drawing from SVG markup, read without a DOM: [What it morphs](https://cesarvenzac.com/morph/docs/sources#any-svg) says what's read.

```typescript
function svg(markup: string): Drawing;
```

### text(font, value, options?)

A word or a line set in a font, each glyph a filled part.

```typescript
function text(font: Font, value: string, options?: TextOptions): Drawing;

type TextOptions = { size?: number; color?: string };
```

### motion(source, options?)

A drawing at rest on `source` that springs to the next when told: pure and immutable, each method returning a new motion.

```typescript
function motion(source: Source, options?: MotionOptions): Motion;

type MotionOptions = Options & { spring?: Spring };
type Motion = {
  readonly morph: Morph;
  readonly t: number;
  readonly velocity: number; // in t a second
  readonly target: 0 | 1;
  readonly source: Source; // headed for, or resting on
  readonly settled: boolean;
  readonly viewBox: Box;
  toward(next: Source): Motion;
  step(seconds: number): Motion;
  jump(): Motion;
  frame(): Part[];
};
```

### attributesOf(part, options?)

A part as a `<path>`'s attributes, for `setAttribute` or markup. An icon's part is `strokeWidth` wide (2 unless said) at a width of 1.

```typescript
function attributesOf(part: Part, options?: PaintOptions): Attributes;

type PaintOptions = { strokeWidth?: number };
type Attributes = {
  d: string;
  fill: string;
  stroke: string;
  "fill-opacity"?: string;
  "fill-rule"?: "evenodd";
  "stroke-width"?: string;
  "stroke-linecap"?: "butt" | "round" | "square";
  "stroke-linejoin"?: "miter" | "round" | "bevel";
  opacity?: string;
};
```

### svgOf(morph, t, options?)

The frame at `t` as an SVG document. `color` is what the current colour is; `width` and `height` give it a size, without which it fills what holds it.

```typescript
function svgOf(m: Morph, t: number, options?: SvgOptions): string;

type SvgOptions = PaintOptions & {
  color?: string;
  width?: number;
  height?: number;
};
```

### nodesData(nodes, closed, digits?)

Nodes back as path data, three decimals unless said: for drawing anchors and handles, or a frame from `shapes`.

```typescript
function nodesData(nodes: Node[], closed: boolean, digits?: number): string;
```

### EVENLY, SOFTLY, PRESS

Soft's steps all off and all on, and the spring that settles without overshoot, `{ stiffness: 260, damping: 32 }`.

### Types

```typescript
type Source = Icon | Drawing;
type Icon = string | readonly string[] | readonly IconElement[];
type IconElement = readonly [tag: string, attributes: Record<string, string | number | undefined>];

type Drawing = { parts: DrawingPart[]; viewBox: Box; em?: number };
type DrawingPart = {
  kind: "fill" | "stroke";
  d: string;
  color?: string;
  opacity?: number;
  width?: number;
  rule?: "nonzero" | "evenodd";
  cap?: "butt" | "round" | "square";
  join?: "miter" | "round" | "bevel";
};
type Box = [x: number, y: number, width: number, height: number];

type Part = {
  d: string;
  width: number;
  fill?: number; // drawings: 0 a stroke, 1 a fill
  color?: string;
  opacity?: number;
  cap?: "butt" | "round" | "square";
  join?: "miter" | "round" | "bevel";
};
type Shape = { nodes: Node[]; closed: boolean; width: number; holes?: Contour[] };
type Contour = { nodes: Node[]; closed: boolean };
type Node = { at: Vec; in?: Vec; out?: Vec };
type Vec = [number, number];

type Method = "soft" | "even" | "index";
type Steps = { shape: boolean; whole: boolean; round: boolean; curves: boolean };
type Extra = "auto" | "split" | "gather";
type Options = { way?: Method | Steps; extra?: Extra };
type Spring = { stiffness: number; damping: number };

type Font = {
  unitsPerEm: number;
  ascender: number;
  descender: number;
  getPath(text: string, x: number, y: number, size: number): FontPath;
  getPaths?(text: string, x: number, y: number, size: number): FontPath[];
  getAdvanceWidth(text: string, size: number): number;
  charToGlyph?(char: string): FontGlyph;
  getKerningValue?(left: FontGlyph, right: FontGlyph): number;
};
type FontGlyph = {
  advanceWidth?: number;
  getPath(x: number, y: number, size: number): FontPath;
};
type FontPath = { toPathData(decimals?: number): string };
```

## React

`@cesarvenzac/morph/react`: client components and hooks, React 18 or later.

### <MorphIcon>

An icon, or any drawing, that springs to the next whenever `icon` changes. Any `<svg>` prop goes on its `<svg>`; it's hidden from assistive tech unless it's named.

```typescript
type MorphIconProps = SVGProps<SVGSVGElement> & {
  icon: Source;
  size?: number | string; // 24
  strokeWidth?: number; // an icon's, 2
  spring?: Spring;
  way?: Method | Steps;
  extra?: Extra;
  reducedMotion?: boolean; // prefers-reduced-motion
};
```

### useMorph(from, to, options?)

A morph kept across renders, made again only when a side or the options say something new: icons written inline are the same icons.

### useMorphing(source, options?)

`MorphIcon`'s motion without its `<svg>`: `{ parts, viewBox, motion }`, springing to each new source.

### <MorphFrame>

A morph drawn at `t`: `morph`, `t`, `size` and `strokeWidth`, any other prop on its `<svg>`.

## The DOM

`@cesarvenzac/morph/dom`, for a page without a framework.

### mount(svg, source, options?)

```typescript
function mount(svg: Element, source: Source, options?: MountOptions): Mounted;

type MountOptions = MotionOptions & PaintOptions & { reducedMotion?: boolean };
type Mounted = {
  to(next: Source): void; // spring there
  set(next: Source): void; // show it at once
  readonly motion: Motion;
  stop(): void;
};
```

### draw(svg, parts, viewBox?, options?)

Parts into an `<svg>`: a `<path>` each, made and taken away as their number changes, drawn after whatever else the `<svg>` holds, each with no attribute left over from the frame before.

## Cost

Making a morph is the costly part: about 8 milliseconds for a pair of Lucide's icons (15 for nine pairs in ten), and about 100 for two words of a dozen letters, measured in Node on one core of a 2.1 GHz server. Do it once and keep the morph, not the sources. A frame then takes a quarter of a millisecond for icons, and 2 to 4 for words.

## Morph's docs

- [Overview](https://cesarvenzac.com/morph.md): Morph any SVG into another without the spikes: icons, filled shapes, words, one shape into several.
- [Getting started](https://cesarvenzac.com/morph/docs/getting-started.md): Install Morph, make a morph, and draw any moment of it: in React, in the page, or on a server.
- [What it morphs](https://cesarvenzac.com/morph/docs/sources.md): Icons, any SVG markup, words set in a font, or drawings made by hand: either side can be any of them, and the two needn't match.
- [Shapes and colours](https://cesarvenzac.com/morph/docs/shapes.md): How pieces pair, how holes open and close, what becomes of the shapes one side has more of, and how colours mix.
- [Playing it](https://cesarvenzac.com/morph/docs/playing.md): Spring from one drawing to the next when something changes: MorphIcon in React, mount in the page, motion for any other clock.
- [Ways to morph](https://cesarvenzac.com/morph/docs/ways.md): Soft, even and index, the three ways side by side, the four steps that make soft what it is, and a frame as anchors and handles.
- [API reference](https://cesarvenzac.com/morph/docs/api.md): Every function and type the package exports, entry by entry: the core, React and the DOM.
