Many particles
Two hundred and forty small white dots drift slowly from side to side across the frame.
init() fills a pool once with positions from random(seed), and seek(local) rewrites each entity's style with update() after every seek, drifting it by noise() at an offset of its own.
- Every seek flushes the page's pools before the frame is captured, so the DOM holds the seek's frame when the seek settles, and a pool added later is flushed the same way.
random(seed)andnoise(x, seed)give the same values on every run, whereMath.random()would give each render a different field (KN-141).- The pool needs a tier with pools, mini-pool and up.
<div id="stage" data-composition-id="dust" data-start="0" data-duration="6" data-width="1280" data-height="720" data-fps="30">
<div class="layer" data-component="dust" data-start="0" data-duration="6">
<div data-pool="dust" data-key="id">
<template><i style="position: absolute; left: 0; top: 0; border-radius: 50%; background: #fff" data-bind-style="style"></i></template>
</div>
</div>
</div>
const { scene, random, noise, styleAt } = wildflower.kinetic;
const DUST = 240;
const SEED = 7;
scene('dust', {
pools: { dust: {} },
init() {
const rnd = random(SEED);
for (let i = 0; i < DUST; i++) {
this.pools.dust.add({ id: i, x: rnd() * 1280, y: rnd() * 720, size: 1.5 + rnd() * 3, style: {} });
}
},
seek(local) {
this.pools.dust.forEach((d) => {
const drift = noise(d.id * 0.37 + local * 0.12, SEED) * 36;
this.pools.dust.update(d.id, {
style: {
width: d.size + 'px',
height: d.size + 'px',
...styleAt(local, { translateX: d.x + drift, translateY: d.y }),
},
});
});
},
});
html, body { margin: 0; background: #0a0b10; }
#stage { position: relative; overflow: hidden; background: #0b0f1a; }
.layer { position: absolute; inset: 0; }
[data-composition-id]:not([data-kinetic-ready]) { visibility: hidden; }
Many particles
The Launch Title demo drifts 240 motes of dust behind its title this way.