Burst
A Burst is an Emitter: it throws count copies of one Child outward around the Origin, spread
evenly clockwise from 12 o’clock unless you aim it. It draws nothing of its own. It has no duration: a Burst lasts
as long as its longest-running Child.
| Field | Takes | If left out |
|---|---|---|
children |
the Child spawned count times: a Shape, another Burst, or a Swirl around either |
required |
count |
how many Children | 5 |
radius |
a length: the distance from the Origin to each Child, animated over the Burst’s duration | [0, 50] |
easing |
a Curve for the Burst’s own radius. Its Children take their own easing. |
linear |
stagger |
a time between one Child’s start and the next; see Stagger | 0 |
delay |
a time to wait before the Burst starts: before any Child starts, and before it throws them | 0 |
restAt |
the Resting frame, a progress from 0 to 1 | the last frame |
angle |
an angle: where the rays point, clockwise from 12 o’clock. One value, not Keyframes. | 0 |
spread |
an angle from 0 to 360: the arc the rays cover, centred on angle |
360 |
orient |
true to turn each Child to face its ray |
off |
The Burst’s radius and each Child’s own fields are separate. radius: [10, 110] on the Burst
moves every Child from 10 to 110 pixels out, while radius on a circle Child is that circle’s own
size.
import { Motly, rand } from '@motly/gsap';import { gsap } from 'gsap';
gsap.registerPlugin(Motly);
const spec = { kind: 'burst', count: 8, // The Burst's own radius: how far its Children are from the Origin. radius: [10, 110], easing: 'ease-out', restAt: 0.4, children: { kind: 'circle', radius: [rand(6, 12), 0], fill: 'deeppink', duration: 1 },};
gsap.effects.burst('.origin', { spec, repeat: -1, repeatDelay: 0.5 });<div class="origin"></div>A Burst’s last frame is usually empty, because its Children shrink or fade away, so give it a
restAt where it still shows something.
Aiming: angle and spread
Section titled “Aiming: angle and spread”angle turns the rays, and spread narrows them to an arc. The two rules differ on purpose:
- At
spread: 360, the default, the rays ring the Origin: the first atangle, the rest 360 /countapart, so the last does not land on the first. - Below 360, the arc is centred on
angle, both edges included,spread/ (count− 1) apart. You aim a cone by its middle:angle: 0, spread: 70is a cannon pointing straight up.
import { each, Motly, rand } from '@motly/gsap';import { gsap } from 'gsap';
gsap.registerPlugin(Motly);
// Each piece holds its size for most of its flight, then shrinks away.const piece = { fill: each(['#ffd166', '#ef476f', '#06d6a0']), scale: [1, 1, 0], duration: rand(1.1, 1.6),};
// A cannon: 14 clumps fanned over 70°, centred on angle 0, straight up. Each clump is a small// Burst of its own, so the confetti scatters instead of lining up on one arc.const spec = { kind: 'burst', count: 14, angle: 0, spread: 70, radius: [0, rand(170, 220)], easing: 'ease-out', restAt: 0.35, children: { kind: 'burst', count: 6, radius: [0, rand(10, 45)], delay: rand(0, 0.1), children: each([ { kind: 'polygon', points: 4, radius: rand(3, 6), angle: [0, rand(-180, 180)], ...piece }, { kind: 'circle', radius: rand(2, 4), ...piece }, ]), },};
gsap.effects.burst('.origin', { spec, repeat: -1, repeatDelay: 0.4 });<div class="origin"></div>
<style> .origin { position: absolute; bottom: 24px; left: 50%; }</style>A single Child goes along angle, so count: 1 with an angle is one aimed throw. spread: 0
sends every Child along the same ray; with a stagger they leave one after another, as a jet.
import { Motly } from '@motly/gsap';import { gsap } from 'gsap';
gsap.registerPlugin(Motly);
// spread 0 sends every Child along one ray; stagger lets them out one after another.const spec = { kind: 'burst', count: 14, angle: 50, spread: 0, stagger: 0.06, radius: [0, 240], easing: 'ease-out', restAt: 0.5, children: { kind: 'circle', radius: [7, 1], fill: ['#22d3ee', '#8b5cf6'], duration: 0.9 },};
gsap.effects.burst('.origin', { spec, repeat: -1, repeatDelay: 0.3 });<div class="origin"></div>
<style> .origin { position: absolute; bottom: 40px; left: 30%; }</style>angle takes rand(), so each Instance can be turned differently, and each(), so each Burst in a
Burst of Bursts can point its own way.
Facing the throw: orient
Section titled “Facing the throw: orient”A Child’s angle is its own: a line runs from 12 o’clock to 6 whichever way it is thrown.
orient: true turns each Child to face its ray, with its own angle added on top, so streaks,
sparks and arrows point outward.
import { Motly } from '@motly/gsap';import { gsap } from 'gsap';
gsap.registerPlugin(Motly);
// Streaks: a line runs from 12 o'clock to 6, so without orient every one points straight up.const streaks = (orient) => ({ kind: 'burst', count: 12, radius: [15, 80], orient, restAt: 0.5, children: { kind: 'line', radius: [3, 18, 0], stroke: '#ffd166', strokeWidth: 3, duration: 0.8, },});
const [left, right] = document.querySelectorAll('.origin');gsap.effects.burst(left, { spec: streaks(false), repeat: -1, repeatDelay: 0.4 });gsap.effects.burst(right, { spec: streaks(true), repeat: -1, repeatDelay: 0.4 });<main> <figure><div class="origin"></div><figcaption>orient left out</figcaption></figure> <figure><div class="origin"></div><figcaption>orient: true</figcaption></figure></main>
<style> main { display: flex; gap: 3rem; } figure { display: grid; place-items: center; width: 12rem; height: 220px; margin: 0; } figcaption { align-self: end; opacity: 0.6; font: 0.8rem ui-monospace, monospace; }</style>A Burst Child turns its rays with it, so a fan inside a ring points outward. The Child a Swirl wraps faces the ray, not the Swirl’s curve. The turn is worked out once, when the Spec is resolved, so orienting costs nothing per frame.
Different Children
Section titled “Different Children”children takes each([...]) to hand different Children out in turn: the first Child gets the
first Spec, the second the second, and so on, starting over at the end.
import { each, Motly, rand } from '@motly/gsap';import { gsap } from 'gsap';
gsap.registerPlugin(Motly);
// each([...]) hands different Children out in turn: circle, star, polygon, circle, …const shared = { radius: [rand(6, 12), 0], angle: [0, rand(-180, 180)], duration: 1 };
const spec = { kind: 'burst', count: 12, radius: [0, 110], restAt: 0.4, children: each([ { kind: 'circle', fill: '#ef476f', ...shared }, { kind: 'star', points: 5, fill: '#ffd166', ...shared }, { kind: 'polygon', points: 3, fill: '#06d6a0', ...shared }, ]),};
gsap.effects.burst('.origin', { spec, repeat: -1, repeatDelay: 0.5 });<div class="origin"></div>A Burst of Bursts
Section titled “A Burst of Bursts”A Child can itself be a Burst. Each inner Burst is thrown by the outer one and opens where it was thrown, which is how fireworks are built.
import { each, Motly, rand } from '@motly/gsap';import { gsap } from 'gsap';
gsap.registerPlugin(Motly);
// A Burst whose Children are Bursts: each one opens where its parent threw it.const spec = { kind: 'burst', count: 6, radius: [0, 90], restAt: 0.5, children: { kind: 'burst', count: 8, radius: [0, rand(20, 35)], delay: 0.25, children: { kind: 'circle', radius: [rand(3, 5), 0], fill: each(['#ffd166', '#ef476f', '#118ab2']), duration: 0.8, }, },};
gsap.effects.burst('.origin', { spec, repeat: -1, repeatDelay: 0.5 });<div class="origin"></div>rand() in an inner Burst resolves separately for each copy, so no two inner Bursts are the same
unless you want them to be.