Skip to content

Fireworks

The fireworks simulation creates a continuous display with 16 unique explosion variants, 3D depth effects, and configurable scale. Fireworks are launched automatically and explode into one of the available variants.

Examples

Basic

An auto-spawning firework display with default settings.

<template>
    <EffectDemo>
        <canvas ref="canvasRef"></canvas>
    </EffectDemo>
</template>

<script
    setup
    lang="ts">
    import { onMounted, onUnmounted, ref } from 'vue';
    import { createFireworks } from '@basmilius/sparkle';

    const canvasRef = ref<HTMLCanvasElement>();
    let sim: ReturnType<typeof createFireworks> | null = null;

    onMounted(() => {
        if (canvasRef.value) {
            sim = createFireworks();
            sim.mount(canvasRef.value).start();
        }
    });

    onUnmounted(() => {
        sim?.destroy();
        sim = null;
    });
</script>

Manual control

Click anywhere on the canvas to fire a random explosion at that position.

Click anywhere to fire a random explosion

<template>
    <EffectDemo
        ref="containerRef"
        clickable>
        <canvas ref="canvasRef"></canvas>

        <span class="effect-demo__hint">Click anywhere to fire a random explosion</span>
    </EffectDemo>
</template>

<script
    setup
    lang="ts">
    import { onMounted, onUnmounted, ref } from 'vue';
    import { createFireworks, FIREWORK_VARIANTS } from '@basmilius/sparkle';

    const canvasRef = ref<HTMLCanvasElement>();
    const containerRef = ref<HTMLDivElement>();
    let sim: ReturnType<typeof createFireworks> | null = null;
    let variants: string[] = [];

    function onClick(evt: MouseEvent): void {
        if (!sim || !containerRef.value || variants.length === 0) {
            return;
        }

        const rect = containerRef.value.getBoundingClientRect();
        const variant = variants[Math.floor(Math.random() * variants.length)];

        sim.launch(variant, {
            x: evt.clientX - rect.left,
            y: evt.clientY - rect.top
        });
    }

    onMounted(() => {
        variants = [...FIREWORK_VARIANTS];

        if (canvasRef.value && containerRef.value) {
            sim = createFireworks({autoSpawn: false});
            sim.mount(canvasRef.value).start();
            containerRef.value.addEventListener('click', onClick);
        }
    });

    onUnmounted(() => {
        containerRef.value?.removeEventListener('click', onClick);
        sim?.destroy();
        sim = null;
    });
</script>

Variant picker

Try each of the 16 variants individually using the buttons.

<template>
    <EffectDemo ref="containerRef">
        <canvas ref="canvasRef"></canvas>

        <div
            v-if="ready"
            class="effect-demo__controls">
            <button
                v-for="variant in variants"
                :key="variant"
                @click="fire(variant)">
                {{ variant }}
            </button>
        </div>
    </EffectDemo>
</template>

<script
    setup
    lang="ts">
    import { onMounted, onUnmounted, ref } from 'vue';
    import { createFireworks, FIREWORK_VARIANTS } from '@basmilius/sparkle';

    const canvasRef = ref<HTMLCanvasElement>();
    const containerRef = ref<HTMLDivElement>();
    const ready = ref(false);
    const variants = ref<string[]>([]);
    let sim: ReturnType<typeof createFireworks> | null = null;

    function fire(variant: string): void {
        if (!sim || !containerRef.value) {
            return;
        }

        const rect = containerRef.value.getBoundingClientRect();

        sim.launch(variant, {
            x: rect.width * (0.2 + Math.random() * 0.6),
            y: rect.height * (0.15 + Math.random() * 0.35)
        });
    }

    onMounted(() => {
        variants.value = [...FIREWORK_VARIANTS];

        if (canvasRef.value) {
            sim = createFireworks({autoSpawn: false});
            sim.mount(canvasRef.value).start();
            ready.value = true;
        }
    });

    onUnmounted(() => {
        sim?.destroy();
        sim = null;
    });
</script>

Scaling

Use the scale option to control the overall size of all effects:

typescript
// Smaller, more subtle fireworks
const fireworks = createFireworks({scale: 0.5});

// Bigger, more dramatic fireworks
const fireworks = createFireworks({scale: 2});

Variants

There are 16 variants organized in four categories.

Classic

VariantDescription
peonyClassic spherical burst with round particles.
chrysanthemumDense burst with long trailing particles and sparkle.
willowParticles fall gracefully with very long trails, like a weeping willow.
palmNarrow upward cone that arcs into drooping trails.
brocadeDense golden shimmer trails in warm amber tones.
horsetailNarrow upward fountain with extreme gravity, creating a cascade.

Geometric

VariantDescription
ringParticles form a perfect circle with diamond shapes.
concentricTwo concentric rings at different sizes with complementary colors.
saturnA filled 3D sphere with a tilted elliptical ring around it.

Shapes

VariantDescription
heartParticles follow a parametric heart curve.
flowerRose curve that creates a petal pattern with 4-8 lobes.
spiralMultiple arms that spiral outward like a galaxy.
dahliaMulti-colored petal clusters with alternating hues.

Effects

VariantDescription
crackleStar-shaped particles that create spark flashes when dying.
crossetteParticles that split into 4 sub-explosions mid-flight.
strobeParticles that blink on/off at ~10Hz.