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.