Get started

Install once. Ship motion fast.

Installation

NPM

npm install @sebastienrousseau/sine-wave-generator

CDN (unpkg)

<script src="https://unpkg.com/@sebastienrousseau/sine-wave-generator"></script>

CDN (jsDelivr)

<script src="https://cdn.jsdelivr.net/npm/@sebastienrousseau/sine-wave-generator"></script>

Quick Start

Browser (script tag)

<canvas id="sine"></canvas>
<script src="https://unpkg.com/@sebastienrousseau/sine-wave-generator"></script>
<script>
  const generator = new SineWaveGenerator({
    el: "#sine",
    waves: [{ amplitude: 26, wavelength: 120, speed: 0.8 }]
  });
  generator.start();
</script>

CommonJS / ESM

const { SineWaveGenerator } = require(
  "@sebastienrousseau/sine-wave-generator"
);

const generator = new SineWaveGenerator({
  el: document.getElementById("sine"),
  maxPixelRatio: 2,
  waves: [{ amplitude: 26, wavelength: 120, speed: 0.8 }]
});

generator.start();

TypeScript

Types are bundled with the package. Import the interfaces directly:

import { SineWaveGenerator, Wave, Ease } from "@sebastienrousseau/sine-wave-generator";

const gen = new SineWaveGenerator({
  el: "#canvas",
  waves: [{ amplitude: 30, wavelength: 140, speed: 0.8 }],
});

gen.start();

The package exports SineWaveGenerator, Wave, and Ease with full JSDoc annotations for editor autocompletion.

Common patterns

Production‑ready by default.

Hero background

Full-bleed canvas with layered waves and low opacity.

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();

Responsive container

Use ResizeObserver for components that resize independently.

const gen = new SineWaveGenerator({ el: canvas });
const ro = new ResizeObserver(() => gen.resize());
ro.observe(canvas.parentElement);

gen.start();

Pointer interaction

Bind to pointer move for responsive phase shifts.

canvas.addEventListener("pointermove", (event) => {
  const y = event.clientY / canvas.clientHeight;
  gen.waves.forEach((wave) => {
    wave.phase = y * Math.PI * 2;
  });
});