SVG✨ Premium

Morphing Shape

A solid SVG shape that smoothly turns from a diamond into a circle, a star and a square while shifting hue — a real morph that also runs smoothly in Safari.

CSSMorphing

Updated

This effect is part of Effect.Labs — 840 vanilla effects, some free, some premium. SVG has 30 effects, including 3 free. Explore the category →

3 usage examples

Large hero shape — ceramics studio — Morphing Shape example 1

① Large hero shape — ceramics studio

WhenThe home page of a ceramics studio: on the left the headline "Clay takes shape in your hands", the text and two buttons; on the right, the 206 px shape slowly moving from one outline to the next above a plinth shadow, like a piece being thrown.
WhyThe morph tells the craft without a photo: a material that changes shape. Placed beside the text rather than under it, it brings the hero to life without hurting legibility.
Settings--mrph-size:206px, --mrph-page:transparent, --mrph-root-h:0px; dur="6s" on both <animate> tags for a calm pace; terracotta colors values="#c8643f;#dd9a4a;#b9483a;#c97c6c;#c8643f" and a starting fill="#c8643f".
"Listening…" badge — voice notes app — Morphing Shape example 2

② "Listening…" badge — voice notes app

WhenA dictated-notes app: while listening, the round badge of the mic button keeps changing shape next to the "Listening…" label and the duration. A tap pauses it: the shape freezes on the diamond and the label becomes "Paused — tap to resume".
WhyA living shape says "I'm capturing" without a speaker icon or waveform; frozen, it says the opposite. The text next to it keeps the information available to everyone.
Settings--mrph-size:34px inside a 38 px badge; teal hues values="#2dd4bf;#22d3ee;#38bdf8;#5eead4;#2dd4bf"; dur="2.4s". The scene button calls pauseAnimations() + setCurrentTime(0) or unpauseAnimations() on its badge's SVG (standard SVG methods).
"Freeze the star!" game — early-learning app for kids — Morphing Shape example 3

③ "Freeze the star!" game — early-learning app for kids

WhenA game screen for 4 to 6 year-olds: the shape morphs inside a large card, and the child taps the card when the star shows up. The game freezes the shape and says "Well done, it's the star!" or "Almost! That was the circle."; a second tap restarts it.
WhyThe morph becomes the game mechanic: you have to recognize a shape while it is changing. The effect's four shapes are precisely the basic shapes children learn at that age.
SettingsDefault colors and duration (4 s); --mrph-size:132px. On tap, the scene calls pauseAnimations() then reads getCurrentTime() modulo the duration: close to 2 s = star, 0 = diamond, 1 = circle, 3 = square.

How it works

The drawing is a single <path class="mrph-shape"> in a 120 × 120 unit SVG. The four shapes (diamond, circle, five-pointed star, square) are written with the same structure: 20 anchor points joined by 20 cubic Bézier curves. Straight sides are curves whose handles stay on the line; the circle uses arc handles. Since every shape has the same number and type of commands, the browser can compute every in-between shape: the change is continuous, with no jump.

The animation is SMIL: an <animate attributeName="d"> runs through the four paths in 4 s (a quarter of the cycle per change, soft acceleration and braking through keySplines=".42 0 .58 1"), then returns to the diamond and starts again. A second <animate attributeName="fill">, on the same clock, slides the color from indigo #6366f1 to violet #8b5cf6, magenta #d946ef and pink #ec4899.

Why SMIL rather than the CSS d property: Safari does not support d in CSS, so the shape would stay frozen there. <animate> on the d attribute is supported by Chrome, Firefox and Safari. The small script only handles reduced motion; there is no generic class or CSS animation name: everything is prefixed mrph-, so the code can sit next to any other effect.

Accessibility

  • Decorative by default: the SVG has aria-hidden="true" and focusable="false", screen readers skip it. If the shape carries meaning (a "listening" state, for instance), say it in visible text next to it, as in the voice-notes example.
  • Reduced motion: a SMIL animation cannot be stopped with CSS. The script reads prefers-reduced-motion: reduce, pauses each drawing with pauseAnimations() and rewinds it (setCurrentTime(0)): a crisp indigo diamond remains. It also follows a change of the setting during the visit and restarts the animation if the option is turned off.
  • Nothing to operate: the effect reacts to neither pointer nor keyboard; no focus trap. For an interactive use (pause on click), use a real <button> and the standard SVG methods, see the FAQ.
  • Pace: a full cycle lasts 4 s, with no blinking or flashing; the color change is gradual.

Browser compatibility

SMIL <animate> on the d attribute and on fill, pauseAnimations() / setCurrentTime(), prefers-reduced-motion media query. Measured in Chromium, Firefox and WebKit (Playwright): 0 errors, continuous in-between shapes for every pair (same path within 50 ms in all 3 engines), two independent copies, a lone copy still drawn when another copy is hidden, clean stop under reduced motion. The morph itself works in much older versions; the versions below are those where reduced motion is honored too.

Chrome 74+✓ Full (measured)
Firefox 63+✓ Full (measured)
Safari 10.1+✓ Full (measured in WebKit)
Edge 79+✓ Full (Chromium engine)
Safari iOS 10.3+✓ WebKit engine, not verified on a real device
Chrome Android 74+✓ Full (Chromium engine)

Without SMIL, the path keeps its starting value: a still indigo diamond. Without JavaScript, only the reduced-motion stop is missing; the morph runs normally.

The code

HTML structure to paste into your page (the CSS + JS come with your purchase):

index.html — structure
<div class="fx-0601-root">
  <div class="mrph-stage">
    <svg class="mrph-svg" viewBox="0 0 120 120" aria-hidden="true" focusable="false">
      <path class="mrph-shape" fill="#6366f1" d="…diamond…">
        <animate class="mrph-d" attributeName="d" dur="4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;.25;.5;.75;1" keySplines="…" values="…diamond;circle;star;square;diamond…"/>
        <animate class="mrph-fill" attributeName="fill" dur="4s" repeatCount="indefinite" calcMode="spline" keyTimes="0;.25;.5;.75;1" keySplines="…" values="#6366f1;#8b5cf6;#d946ef;#ec4899;#6366f1"/>
      </path>
    </svg>
  </div>
</div>

One-time payment, no subscription — the code is yours forever

Customize

Options passed to the API or data-* attributes:

Option / propertyDefaultEffect
Size (CSS — --mrph-size) 120px Side of the drawing. 100% makes it follow the parent's width; the SVG keeps its proportions.
Block background and height (CSS — --mrph-page, --mrph-root-h) #0a0a0f / 300px --mrph-page:transparent and --mrph-root-h:0px to set the shape on your own background, inside a button or a card.
Cycle length (HTML — dur on both <animate> tags) 4s Use the same value on both tags to keep color and shape in sync (e.g. dur="6s" for a calm background).
Colors (HTML — values of the fill animation) #6366f1;#8b5cf6;#d946ef;#ec4899;#6366f1 One color per shape (diamond, circle, star, square), the first one repeated at the end to loop without a jump. Also change fill on the <path> (color when nothing animates).
Pace of each change (HTML — keySplines) .42 0 .58 1 (×4) Acceleration curve of each quarter cycle. 0 0 1 1 gives an even motion, with no visible rest on each shape.
Shapes (HTML — values of the d animation) diamond; circle; star; square; diamond Each shape must keep exactly the same structure (one M, then 20 C, then Z): otherwise the browser jumps from one shape to the next instead of blending them.

FAQ

A browser can only blend two paths that have the same number of commands, of the same type, in the same order. The four shapes provided all have 20 cubic C curves. For a new shape, start from an existing one and move its points, or have it redrawn as 20 cubics in a vector editor before pasting it into values.
The morph is a SMIL animation, driven by the SVG's own methods: svg.pauseAnimations() freezes the image, svg.unpauseAnimations() resumes, svg.setCurrentTime(0) goes back to the diamond. Call them on the .mrph-svg of the copy concerned, from a real <button>. CSS animation-play-state has no effect on SMIL.
Yes. The effect animates the d attribute with SMIL, which Safari supports; the CSS d property does not exist in Safari, and a shape animated that way would stay frozen there. Measured in WebKit with the same rendering as Chrome and Firefox.