webdevpuneet.com

Canvas Mesh Gradient Background — Free Animated Blurred Blob Effect

Canvas Mesh Gradient Background · Animations · Plain HTML, CSS & JS · Live preview

CategoryAnimations

Copy & paste

Source Code

<section class="cmg-wrap">
  <canvas class="cmg-canvas" id="cmgCanvas"></canvas>
  <div class="cmg-content">
    <span class="cmg-tag">canvas 2d · blurred radial blobs</span>
    <h1>Design, reimagined</h1>
    <p>Soft color blobs drift and orbit slowly, blending into a living mesh gradient.</p>
    <button class="cmg-btn">Start free trial</button>
  </div>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

CSS-blurred canvas
Sharp circles drawn in JS, softened by a compositor filter.
Deliberately low-res canvas
60% resolution since the blur erases fine detail anyway.
Elliptical orbits
Each blob drifts around its own home point, not randomly.
Independent periods
Different speed and phase per blob avoids visible repetition.
Radial gradient blobs
createRadialGradient fades each color to transparent.
Opaque base fill
No transparent gaps between overlapping gradient edges.
Legible overlay text
Content layer uses text-shadow to stay readable.
Zero dependencies
Pure Canvas 2D, CSS filters, and vanilla JS.

About this UI Snippet

Canvas Mesh Gradient Background — Orbiting Blobs Softened by CSS

Screenshot of the Canvas Mesh Gradient Background snippet rendered live

The animated mesh gradient look — soft, saturated color fields blending into each other — is everywhere in modern SaaS and product marketing pages. This snippet builds it with a small trick: draw sharp, high-contrast radial gradient circles on a low-resolution canvas, then let a single CSS filter: blur() on the canvas element do the actual softening. The blur is free, GPU-accelerated, and completely decoupled from the animation logic.

Draw sharp, let CSS blur it

Every blob is a plain createRadialGradient circle — full color at the center fading to transparent at the edge — drawn with hard mathematical precision. None of that softness is visible directly: .cmg-canvas { filter: blur(60px) saturate(1.3) } in the CSS is what turns those crisp circles into the smooth, melting color fields the effect is known for. Because the blur is a compositor-level CSS filter rather than a canvas shadow or manual convolution, it costs almost nothing extra to animate — the JavaScript never has to know it's happening.

Drawing small on purpose

resize() deliberately sizes the canvas's backing store to only 60% of the wrapper's dimensions. Since a 60px blur is going to erase most fine detail anyway, there is no benefit to drawing at full resolution — doing so would just spend more pixel-fill time per frame for a visually identical result once blurred. This is the inverse of the usual high-DPI advice, and it's a useful pattern any time a canvas feeds into a heavy CSS filter.

Orbits instead of random walks

Each blob in BLOBS has a hx, hy home position and orbits it on an ellipse defined by orbitX, orbitY, its own speed, and a phase offset — cx = (hx + cos(t * speed + phase) * orbitX) * W. Because every blob's period, radius, and starting phase are different, the five orbits drift in and out of alignment with each other indefinitely without ever repeating in a way a viewer would notice, and — unlike a random-walk approach — the motion is perfectly smooth and perfectly loops mathematically rather than needing manual bounds-checking.

Layering and readability

The wrapper's actual content sits in a separate stacking layer above the canvas with its own text-shadow for legibility against a busy background, and the canvas itself paints an opaque base color before drawing blobs so partially-transparent gradient edges never reveal a transparent hole. Pair this background with a gradient mesh hero layout, or swap the palette for a calmer duotone version behind a glowing stars card.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSFive color blobs orbit and blend behind the hero content.
  2. 2
    Note the CSS blur.cmg-canvas uses filter: blur(60px) — that's the actual softening.
  3. 3
    Resize the windowThe canvas rescales at 60% resolution and keeps animating.
  4. 4
    Add a blobPush a new object into BLOBS with its own home, orbit, and color.
  5. 5
    Change the paceLower every speed value for a slower, more ambient drift.
  6. 6
    Adjust the blur amountIncrease blur() for a softer, more diffuse mesh.

Real-world uses

Common Use Cases

SaaS marketing heroes
Provide a trendy animated backdrop behind headline text, using sharp circles drawn in JavaScript and softened by a compositor blur filter.
Landing page sections
Pair with a gradient mesh hero layout elsewhere, with blobs orbiting elliptically around their own home points.
App onboarding backdrops
Give welcome screens a soft, colourful moving background, drawn at 60% resolution since the blur hides fine detail anyway.
Card and panel backgrounds
Place behind a glowing stars card for a layered, premium feel, with independent periods preventing visible repetition.
Looping presentation backgrounds
Capture frames for a pitch deck or video, since each blob moves with its own speed and phase for a long non-repeating cycle.
Related: Canvas Star Trail Cursor
See the Canvas Star Trail Cursor for a related animations pattern worth pairing with this one.
Related: SVG Liquid Text Wave
See the SVG Liquid Text Wave for a related animations pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The JavaScript never blurs anything — it draws plain, sharp radial gradient circles. The softening comes entirely from a single CSS filter, filter: blur(60px) saturate(1.3), applied to the canvas element itself in the stylesheet. That means the blur is handled by the browser's compositor, not by any per-pixel canvas code, which is both simpler and considerably cheaper than a manual convolution.

A 60px CSS blur erases almost all fine detail regardless of how sharp the source pixels are, so drawing at full resolution would spend extra fill-rate cost every frame for a result that looks identical once blurred. Sizing the canvas backing store smaller than its displayed size and letting CSS scale it up (along with the blur) keeps the animation loop cheaper without any visible quality loss.

Each blob orbits its own home position on an ellipse with its own independent speed and starting phase offset. Because no two blobs share a period, radius, or phase, their positions relative to each other drift continuously and take an extremely long time to realign into any previous configuration — long enough that a viewer never perceives a loop, even though the underlying motion is just combined sine and cosine waves.

Each blob's gradient fades from full color at its center to fully transparent (rgba(0,0,0,0)) at its edge. If the canvas were left transparent underneath, the areas between and around blobs would show through to whatever is behind the canvas rather than blending into a continuous color field. Painting an opaque base fill first guarantees every pixel has a solid color to blend against.

Move the canvas ref, resize() call, and requestAnimationFrame loop into a mount effect, and cancelAnimationFrame the stored frame id on unmount. Keep the CSS blur filter on the canvas element's class, since that part of the effect lives entirely in CSS and needs no JavaScript wiring at all — only the drawing loop needs a lifecycle hook.