Skip to content

Latest commit

 

History

76 Commits

Folders and files

Repository files navigation

Dynamowaves

Lightweight, dependency-free SVG wave templates that generate a new path every time they render. Each wave is a standard custom element (<dynamo-wave>) that keeps its authored host in the DOM, renders an SVG inside it, and can morph or animate on demand.

Documentation + live examples

Features

  • Drop-in custom element – include <dynamo-wave> anywhere in your markup; classes, styles, and IDs flow through automatically.
  • Deterministic or generative – seed waves for reproducible shapes, or let them randomize and re-render via Intersection Observer triggers.
  • Rich data attributes – configure direction, variance, anchoring, animation speed, observation behavior, and more without writing JS.
  • Runtime controls – programmatic API (generateNewWave, play, pause) with TypeScript definitions plus a dynamo-wave-complete event hook.
  • Animation aware – responds to live prefers-reduced-motion changes and cancels animation/observer work while detached.

Installation

npm

npm install dynamowaves
// Registers the <dynamo-wave> custom element globally
import 'dynamowaves';

CDN or direct script

<!-- Local copy -->
<script src="/path/to/dynamowaves.js"></script>

<!-- jsDelivr CDN, pinned to the compatible 2.x line -->
<script src="https://cdn.jsdelivr.net/npm/dynamowaves@2/dist/dynamowaves.min.js" crossorigin="anonymous"></script>

Angular

  1. Add the script to the angular.json scripts array:
    "scripts": [
      "node_modules/dynamowaves/dist/dynamowaves.js"
    ]
  2. Opt in to custom elements support:
    import { NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
    
    @NgModule({
      // ...
      schemas: [CUSTOM_ELEMENTS_SCHEMA]
    })
    export class AppModule {}

Quick start

<dynamo-wave class="fill-theme"></dynamo-wave>

<style>
  .fill-theme { fill: var(--theme); }
</style>

Data attributes

Attribute Default Purpose
data-wave-points 6 Integer anchor count, clamped to 2–1000.
data-wave-variance 3 Finite point deviation, clamped to -100–100.
data-variance unset Legacy alias for data-wave-variance.
data-wave-seed generated Recorded Base64 path or plain deterministic seed.
data-start-end-zero false Anchors endpoints on the base edge.
data-wave-face top Orientation of the wave.
data-wave-speed 7500 Positive loop duration in milliseconds.
data-wave-animate false The exact string true enables automatic playback.
data-wave-observe unset once or repeat, with an optional root margin.

Numeric bounds and lifecycle hardening described here were added in 2.2.1; see CHANGELOG.md.

All attributes are observed at runtime: changing one after render re-renders or reconfigures the wave immediately (a running loop resumes with the new settings).

Reusing wave seeds

<dynamo-wave id="hero-wave" data-wave-animate="true"></dynamo-wave>
<script>
  const heroSeed = document.getElementById('hero-wave')?.getAttribute('data-wave-seed');
  if (heroSeed) {
    const footerWave = document.createElement('dynamo-wave');
    footerWave.setAttribute('data-wave-seed', heroSeed);
    document.body.appendChild(footerWave);
  }
</script>

JavaScript API

import {
  DynamoWave,
  generateWave,
  parsePath,
  interpolateWave,
  encodeWaveSeed,
  decodeWaveSeed,
} from 'dynamowaves';

ESM and CommonJS expose the same six names. Direct browser scripts expose them on globalThis.Dynamowaves.

Instance method Description
generateNewWave(duration = 800) Morph once to a new random path.
play(duration?) Start a continuous loop.
pause() Stop a loop or cancel an active one-off morph.

pause() stays authoritative across geometry, connection, and motion-preference changes. A later play() resumes a paused loop; detached playback requests schedule no frames until reconnection. Non-finite generateNewWave() durations use 800 ms.

dynamo-wave-complete fires after a one-off morph and after every completed loop cycle. Its detail is { duration, direction: 'horizontal' | 'vertical' }.

Practical ideas

See src/lib/content/examples.md or the docs site.

Accessibility

  • Generated SVGs are decorative and hidden from assistive technology.
  • Continuous motion stops when reduced motion is enabled; new one-off morphs use one millisecond, and active morphs finish immediately.
  • The module imports safely during SSR. Reuse a recorded seed when the first client-rendered shape must be identical.

Development

git clone https://github.com/mzebley/dynamowaves.git
cd dynamowaves
npm install
npm run build
npm test
npx playwright install chromium
npm run test:browser

npm run build remains the publishable library build. The documentation is a fully prerendered SvelteKit/mdsvex site that imports the local library source:

npm run dev:docs       # local docs development
npm run build:docs     # library, Zebkit, and prerendered docs
npm run check:docs     # Svelte and Zebkit authored-markup checks
npm run preview:docs   # preview the production docs build
npm run verify:docs    # rendered Zebkit verification against the preview

Run generated Zebkit steps serially: build before check, and restart the preview after the generated runtime or CSS changes.

License

ISC © Mark Zebley

About

Buttery smooth, animatable SVG wave HTML templates that generate themselves on render.

Topics

Resources

Stars

44 stars

Watchers

2 watching

Forks

Releases

Used by

Contributors

Languages