Icon morphs
One icon turning into another, three ways side by side: in the order its paths were written, as most libraries do; evenly resampled, as flubber does; and softly, matched by shape, moved as a whole and rounded halfway, so no frame grows a spike.
In order
Evenly
Softly
Two strokes turn an eighth. In order they fold through each other; point by point they cut across the turn.
// 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 one smooth curve, 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);
path.setAttribute("d", curve(soft, closed, ease));
In order
Both icons' paths are rewritten as the same kind of curve, the shorter list split until the two are as long, and each control point slides in a straight line to the one in the same place in the other list. Nothing knows which part of one icon resembles which part of the other, so a stroke can become any other, the shapes fold through each other, and a circle spins into a square through a spiky diamond.
Evenly
Each stroke is laid out as evenly spaced points, the strokes are paired up, and each pair starts where its points have least far to go; then every point slides in a straight line. The folding stops. What's left is subtler: a stroke that turns cuts across the arc it should follow and comes up short, a corner the second icon has appears as a kink the moment it's needed, a stroke with no partner shrinks to a dot that vanishes on the last frame, and the shape in between is a polygon.
Softly
The same even points, with each icon's corners kept among them exactly, but paired by shape rather than distance: positions, sizes and turns set aside, which way round and from where does one stroke best become the other? Each stroke is then moved as a whole. Its place, its size and, if it's drawn out like a bar, the way it faces are interpolated on their own, the size by ratio, and only what's left of its shape blends point by point, so a plus becomes an x by turning as one piece, every stroke keeping its length. A round shape has no way it faces, so a heart becomes a star upright, never spun.
Then the frame is softened: its points are blurred along each stroke by a Gaussian about a unit wide, scaled by how far through the morph it is, nothing at either end and most halfway. A corner the next icon needs arrives rounded and tightens as it lands; one the first icon had loosens before it goes. Open strokes are mirrored through their ends before blurring, so straight lines stay straight and ends stay where they are. The points are drawn as one smooth curve, sharp only at an icon's own corners, and only near that icon. Strokes with no partner gather into a dot and shrink away. At either end, every column draws the icons exactly as they are.
The icons are Lucide's, the set every icon on this site comes from.