shape-morph

React

Shape component and morph hooks for React.

The shape-morph/react entry point provides a component and hooks for rendering shapes and morphing in React. Requires React 18+.

<Shape> component

Renders a shape as an inline SVG.

import { Shape } from "shape-morph/react";

<Shape name="Heart" size={32} fill="red" />
<Shape name="Cookie9Sided" size={48} fill="#6750A4" stroke="white" />

Props:

PropTypeDefaultDescription
nameShapeNamerequiredShape to render
sizenumber24Width and height in pixels
fillstring"currentColor"Fill color
strokestring-Stroke color
classNamestring-Class on the <svg> element
styleCSSProperties-Style on the <svg> element

useMorph

Animates between two shapes with a requestAnimationFrame loop and ease-in-out interpolation.

import { useMorph } from "shape-morph/react";

function Avatar({ hovered }: { hovered: boolean }) {
  const { clipPath, progress } = useMorph("Circle", "Heart", {
    progress: hovered ? 1 : 0,
    duration: 300,
  });

  return (
    <img
      style={{
        clipPath,
        transform: `rotate(${progress * 90}deg)`,
      }}
      src="/avatar.png"
    />
  );
}

Change the target progress and the hook smoothly animates from the current position.

Options

OptionTypeDefaultDescription
progressnumber0Target progress (0–1)
durationnumber300Animation duration in ms
sizenumber-Output size for pathD

Return value

PropertyTypeDescription
pathDstringSVG path d attribute
clipPathstringCSS clip-path: polygon(...)
progressnumberCurrent animated progress (0–1)

The progress return value is the eased, animated value - not the target. Use it to sync other animations like rotation or color transitions.

useShape

Returns path data for a single shape. No animation.

import { useShape } from "shape-morph/react";

const { pathD, clipPath } = useShape("Heart", 100);

Return value

PropertyTypeDescription
pathDstringSVG path d attribute
clipPathstringCSS clip-path: polygon(...)
polygonRoundedPolygonThe underlying polygon instance

On this page