# Morph: Ways to morph

> 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.

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

`morph(from, to, way)` takes a way to morph, or `{ way, extra }`. Soft is the default and the reason for the package; the other two are here to compare, and for the drawings they suit.

*Live example on the page: Icon morphs. The three ways side by side on Lucide's icons.* Its source:

```tsx
// A stroke is moved as a whole: where it is, how big it is and which way it
// faces are interpolated apart from its shape. A plus turns into an x; it
// doesn't shrink through the middle, as points moving in straight lines do.
const size = Math.exp(lerp(Math.log(fromSize), Math.log(toSize), t));
const centre = lerpVec(fromCentre, toCentre, t);
const points = fromShape.map((p, i) => {
  const [x, y] = rotate(lerpVec(p, toShape[i], t), turn * t);
  return [centre[0] + size * x, centre[1] + size * y];
});

// Then it's softened along its length: a Gaussian blur over its points that
// peaks halfway and is gone at either end. Corners appear rounded and tighten
// as they arrive, instead of snapping in as kinks.
const soft = soften(points, closed, SOFTEST * Math.sin(Math.PI * t));

// Drawn as a few cubics through anchors chosen once for the whole morph (every
// corner, then as few as keep each frame within 0.04 of its points), sharp only
// at an end's own corners, near that end.
const ease = (i) => 1 - Math.max(cornerFrom[i] ? (1 - t) ** 3 : 0, cornerTo[i] ? t ** 3 : 0);
const nodes = nodesThrough({ points: soft, ease }, closed, anchors);
path.setAttribute("d", nodesData(nodes, closed));
```

## Soft

Pieces are paired by their shape, each moved whole (its place, size and turn apart from its shape), blurred along its length so a corner arrives rounded, and drawn as a few fitted cubic curves, sharp only at an end's own corners near that end. It's `"soft"`, and what `morph` does unless told otherwise.

## Even

`"even"` resamples each outline into points a unit apart, matches them for the least travel and moves them in straight lines, drawn as a polygon: flubber's way.

## Index

`"index"` pairs path commands in the order they were written, as most morphing libraries do. It's right when both sides were drawn alike, the same commands in the same order; otherwise points cross over.

## Steps

Soft is even with four steps on, each switchable alone, to see what each does:

```typescript
import { EVENLY, morph } from "@cesarvenzac/morph";

morph(Plus, X, { ...EVENLY, shape: true }); // even, paired by shape
```

- `shape`: pair points by the shape they make, not by how far they travel.
- `whole`: move each piece whole, its place, size and turn apart from its shape.
- `round`: blur each outline along its length, most halfway, so a corner arrives rounded.
- `curves`: draw fitted cubics rather than a polygon, sharp only at an end's own corners.

`SOFTLY` is all four on, soft itself, and `EVENLY` none.

## Anchors and handles

`shapes(t)` is the frame as an editor shows a path: each piece's nodes, an anchor with its `in` and `out` handles, whether it's `closed`, its `width`, and an island's `holes`. Between 0 and 1, `at` is drawn from them, so the two agree; at 0 and 1 `at` is each side exactly, and `shapes` the way's own take on it. `nodesData(nodes, closed)` writes nodes back as path data. `points(t)` is each part's outline before it's drawn as curves, for measuring.

```typescript
import { nodesData } from "@cesarvenzac/morph";

for (const shape of m.shapes(t)) {
  outline(nodesData(shape.nodes, shape.closed)); // the path
  for (const node of shape.nodes) dot(node.at); // its anchors
}
```

Why each step is there, measured, is in [Morphs without spikes](https://cesarvenzac.com/blog/morphs-without-spikes).

## 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.
