๐Ÿซง bubbly-bg

October 29, 2025 ยท View on GitHub

๐Ÿซง 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/bubbly-bg@1.0.0/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/bubbly-bg@1.0.0/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

OptionTypeDefaultDescription
canvasHTMLCanvasElementauto-createdCanvas element to use
composestring"lighter"Global composite operation
animatebooleantrueWhether to animate bubbles
backgroundstring | function"#2AE"Background color or gradient function
bubbles.countnumberauto-calculatedNumber of bubbles
bubbles.radiusfunctionauto-calculatedFunction returning bubble radius
bubbles.fillfunctionwhite with opacityFunction returning bubble fill color
bubbles.anglefunctionrandomFunction returning movement angle
bubbles.velocityfunctionrandomFunction returning velocity
bubbles.shadowfunctionnullFunction returning shadow config
bubbles.strokefunctionnullFunction returning stroke config
bubbles.objectCreatorfunctiondefault creatorAdvanced: 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