Skip to content
Projects

tipsy/bubbly-bg has 1,616 GitHub stars and 93 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-06 06:14 UTC. Last push 2025-10-29.

How these counts are measured

Beautiful bubbly backgrounds in less than 1kB (750 bytes gzipped)

What you can do

  • 🪶 Lightweight - Only 1.6kB minified, 841 bytes gzipped
  • 🎨 Customizable - Full control over colors, gradients, and animations
  • 🚀 Zero dependencies - Pure vanilla JavaScript
  • 📦 Easy to use - Just include and call bubbly()

Measured star growth

in 24h
0
in 7 days
Update delayed
in 15 days
Update delayed
in 1 month
Update delayed

Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.

README.md

Original

🫧 bubbly-bg

Beautiful bubbly backgrounds in less than 1kB gzipped

npm version jsDelivr downloads License Bundle Size

Live Demo

Bubbly animated


✨ Features

  • 🪶 Lightweight - Only 1.6kB minified, 841 bytes gzipped
  • 🎨 Customizable - Full control over colors, gradients, and animations
  • 🚀 Zero dependencies - Pure vanilla JavaScript
  • 📦 Easy to use - Just include and call bubbly()
  • 🎯 TypeScript support - Full type definitions included
  • 🔧 Flexible - Works with your own canvas or creates one automatically

🚀 Quick Start

Add bubbly to your webpage and call bubbly():

<body>
  ...
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bubbly-bg.js"></script>
  <script>bubbly();</script>
</body>

That's it! Bubbly creates a canvas element with position: fixed and z-index: -1, filling the viewport. It's plug-and-play for most projects.

Custom Canvas

You can also use your own canvas element:

bubbly({ canvas: document.querySelector("#my-canvas") });

📦 Installation

CDN

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/bubbly-bg.js"></script>

npm

npm install bubbly-bg

Direct Download

Download bubbly-bg.js

⚙️ Configuration

All Options

bubbly({
    canvas: document.querySelector("#background"), // default is created and attached automatically
    compose: "lighter", // default is "lighter"
    animate: false, // default is true
    background: (ctx) => "#2AE", // default background, can be a color string or function returning gradient
    bubbles: {
        count: 100, // default is Math.floor((canvas.width + canvas.height) * 0.02)
        radius: () => 4 + Math.random() * 25, // default is () => 4 + Math.random() * window.innerWidth / 25
        fill: () => `hsla(${Math.random() * 360}, 100%, 50%, ${Math.random() * 0.25})`, // default is () => `hsla(0, 0%, 100%, ${Math.random() * 0.1})`
        angle: () => Math.random() * Math.PI * 2, // default is this
        velocity: () => 0.1 + Math.random() * 0.5, // default is this
        shadow: () => ({blur: 4, color: "#fff"}), // default is () => null
        stroke: () => ({width: 2, color: "#fff"}), // default is () => null
        objectCreator: () => ({...}) // advanced: custom bubble object creator
    }
});

Configuration Options

Option Type Default Description
canvas HTMLCanvasElement auto-created Canvas element to use
compose string "lighter" Global composite operation
animate boolean true Whether to animate bubbles
background string | function "#2AE" Background color or gradient function
bubbles.count number auto-calculated Number of bubbles
bubbles.radius function auto-calculated Function returning bubble radius
bubbles.fill function white with opacity Function returning bubble fill color
bubbles.angle function random Function returning movement angle
bubbles.velocity function random Function returning velocity
bubbles.shadow function null Function returning shadow config
bubbles.stroke function null Function returning stroke config
bubbles.objectCreator function default creator Advanced: custom bubble creator

🎨 Examples

Default (Blue with white bubbles)

bubbly();

Black/Red with red bubbles

bubbly({
    background: (ctx) => {
        const gradient = ctx.createLinearGradient(0, 0, ctx.canvas.width, ctx.canvas.height);
        gradient.addColorStop(0, "#111");
        gradient.addColorStop(1, "#422");
        return gradient;
    },
    bubbles: {
        fill: () => `hsla(0, 100%, 50%, ${Math.random() * 0.25})`,
        shadow: () => ({blur: 4, color: "#fff"})
    }
});

Purple with multicolored bubbles

bubbly({
    background: (ctx) => {
        const gradient = ctx.createLinearGradient(0, 0, ctx.canvas.width, ctx.canvas.height);
        gradient.addColorStop(0, "#4c004c");
        gradient.addColorStop(1, "#1a001a");
        return gradient;
    },
    bubbles: {
        fill: () => `hsla(${Math.random() * 360}, 100%, 50%, ${Math.random() * 0.25})`,
        shadow: () => ({blur: 4, color: "#fff"})
    }
});

Yellow/Pink with red/orange/yellow bubbles

bubbly({
    background: (ctx) => {
        const gradient = ctx.createLinearGradient(0, 0, ctx.canvas.width, ctx.canvas.height);
        gradient.addColorStop(0, "#fff4e6");
        gradient.addColorStop(1, "#ffe9e4");
        return gradient;
    },
    compose: "source-over",
    bubbles: {
        fill: () => `hsla(${Math.random() * 50}, 100%, 50%, .3)`,
        shadow: () => ({blur: 1, color: "#fff"})
    }
});

🔧 Advanced Usage

Custom Bubble Creator

For complete control over bubble creation and rendering:

bubbly({
    bubbles: {
        objectCreator: function() {
            return {
                x: Math.random() * canvas.width,
                y: Math.random() * canvas.height,
                r: 10,
                a: Math.random() * Math.PI * 2,
                v: 1,
                draw: (ctx, bubble) => {
                    // Custom drawing logic
                    ctx.fillStyle = "red";
                    ctx.fillRect(bubble.x, bubble.y, bubble.r, bubble.r);
                }
            };
        }
    }
});

📝 TypeScript

Full TypeScript definitions are included:

import { bubbly, BubblyConfig } from 'bubbly-bg';

const config: BubblyConfig = {
    animate: true,
    bubbles: {
        count: 50
    }
};

bubbly(config);

📄 License

Apache-2.0 © David Åse

🤝 Contributing

Contributions, issues and feature requests are welcome!

⭐ Show your support

Give a ⭐️ if this project helped you!


Made with ❤️ by David Åse

Explore related projects