Hero background
Build a subtle, layered hero backdrop that stays performant.
Learn moreShort, focused recipes. Built for shipping.
Build a subtle, layered hero backdrop that stays performant.
Learn moreTie wave amplitude and wavelength to scroll position.
Learn moreUse WebAudio input to drive intensity and color.
Learn moreBalance memory and clarity for battery, balanced, and quality modes.
Learn moreAtmosphere, not distraction.
const gen = new SineWaveGenerator({
el: "#hero",
autoResize: true,
waves: [
{ amplitude: 16, wavelength: 220, speed: 0.6 },
{ amplitude: 10, wavelength: 160, speed: 0.4 }
]
});
gen.start();Give the page depth and calm motion without competing with copy.
Two slow waves create parallax at low contrast. The eye reads the motion as atmosphere, not content.
autoResize: true for responsive headers.Motion that tracks progress.
window.addEventListener("scroll", () => {
const progress = scrollY / (docHeight - innerHeight);
wave.amplitude = 10 + 30 * progress;
wave.wavelength = 140 + 240 * (1 - progress);
});Let users “feel” progression without extra UI.
Amplitude increases while wavelength tightens, so the motion intensifies naturally as users move through the page.
requestAnimationFrame.Sound in, motion out.
const analyser = audioCtx.createAnalyser();
analyser.fftSize = 128;
// Map frequency bins to wave intensity.Turn audio energy into visual rhythm.
The analyser hands you a fresh energy reading many times a second — steady enough that the wave doesn't jitter, fast enough that it still feels live.
Fidelity when you want it. Battery when you need it.
gen.setQualityPreset("balanced");
gen.setQualityPreset("quality");
gen.setQualityPreset("battery");Keep visuals consistent across devices with one switch.
Pixel ratio is the single biggest lever on canvas cost — it sets how many actual pixels get redrawn every frame, not just how many you see on screen.
balanced as the default.battery on mobile or low power.quality for hero moments.Stays sharp when its container changes, not just the window.
const gen = new SineWaveGenerator({ el: canvas, autoResize: true });
gen.start();
// No manual ResizeObserver needed — autoResize already watches
// the canvas element itself, not just the window.Keep the canvas crisp in layouts that resize independently.
autoResize observes the canvas element's own box size via ResizeObserver, in addition to the window resize event, catching layout-driven changes a window listener alone would miss.
autoResize on (the default).maxPixelRatio on high-DPI displays to control memory.