Design & Graphics

MESH GRADIENT GENERATOR

Generate smooth multi-point fluid mesh gradients. Customize color nodes, animation morph speed, blur amount, and export CSS or PNG.

Mesh Color Nodes
Morph Speed 1x
Blur Radius 60px

        
Developer Reference

Core Algorithm & Standalone Script

Standalone, zero-dependency JavaScript implementation powering this tool. Free to inspect, copy, and build upon.

const canvas = document.getElementById('mesh-canvas');
    const ctx = canvas.getContext('2d');
    const stage = document.getElementById('stage');

    const c1 = document.getElementById('c1');
    const c2 = document.getElementById('c2');
    const c3 = document.getElementById('c3');
    const c4 = document.getElementById('c4');

    const speedInput = document.getElementById('input-speed');
    const blurInput = document.getElementById('input-blur');
    const cssOut = document.getElementById('css-output');
    const toast = document.getElementById('toast');

    let t = 0;
    let animId = null;

    function resize() {
      canvas.width = stage.clientWidth;
      canvas.height = stage.clientHeight;
    }

    function drawMesh() {
      ctx.clearRect(0, 0, canvas.width, canvas.height);
      const speed = parseFloat(speedInput.value);
      t += 0.01 * speed;

      const blur = parseInt(blurInput.value);
      document.getElementById('val-blur').textContent = blur + 'px';
      document.getElementById('val-speed').textContent = speed + 'x';

      canvas.style.filter = `blur(${blur}px)`;

      const pts = [
        { x: canvas.width * (0.3 + 0.2 * Math.sin(t)), y: canvas.height * (0.3 + 0.2 * Math.cos(t)), color: c1.value, r: canvas.width * 0.4 },
        { x: canvas.width * (0.7 + 0.2 * Math.cos(t * 0.8)), y: canvas.height * (0.3 + 0.2 * Math.sin(t * 0.8)), color: c2.value, r: canvas.width * 0.4 },
        { x: canvas.width * (0.4 + 0.2 * Math.sin(t * 1.2)), y: canvas.height * (0.7 + 0.2 * Math.cos(t * 1.2)), color: c3.value, r: canvas.width * 0.4 },
        { x: canvas.width * (0.8 + 0.1 * Math.cos(t * 0.5)), y: canvas.height * (0.8 + 0.1 * Math.sin(t * 0.5)), color: c4.value, r: canvas.width * 0.4 }
      ];

      pts.forEach(p => {
        const g = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.r);
        g.addColorStop(0, p.color);
        g.addColorStop(1, 'transparent');
        ctx.fillStyle = g;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
      });

      const css = `background-color: ${c1.value};\nbackground-image: \n  radial-gradient(at 20% 20%, ${c2.value} 0px, transparent 50%),\n  radial-gradient(at 80% 30%, ${c3.value} 0px, transparent 50%),\n  radial-gradient(at 40% 80%, ${c4.value} 0px, transparent 50%);`;
      cssOut.textContent = css;

      animId = requestAnimationFrame(drawMesh);
    }

    function showToast(msg) {
      toast.textContent = msg;
      toast.classList.add('show');
      setTimeout(() => toast.classList.remove('show'), 2000);
    }

    document.getElementById('btn-copy-css').addEventListener('click', () => {
      navigator.clipboard.writeText(cssOut.textContent);
      showToast('CSS Gradient copied!');
    });

    document.getElementById('btn-save-png').addEventListener('click', () => {
      const a = document.createElement('a');
      a.href = canvas.toDataURL('image/png');
      a.download = 'mesh-gradient.png';
      a.click();
    });

    window.addEventListener('resize', resize);
    resize();
    drawMesh();
Copied to clipboard!