Skip to main content

Effect authoring API

An effect is a plain object. It does not require registration or subclassing.

const pulseRing = (options = {}) => ({
name: "pulseRing",
stage: "above",
z: 10,
duration: 1800,
hold: 200,
loop: true,

setup(globe) {
return { color: options.color ?? "#67e8f9" };
},

frame(ctx, globe, t, state) {
const point = globe.project(72.58, 23.03);
if (!point?.visible) return;

ctx.strokeStyle = state.color;
ctx.globalAlpha = 1 - t;
ctx.lineWidth = 2;
ctx.beginPath();
ctx.arc(point.x, point.y, 8 + t * 36, 0, Math.PI * 2);
ctx.stroke();
},

dispose(state, globe) {
// Remove listeners or timers created by setup().
},
});

globe.use(pulseRing());

GlobeEffect fields

FieldMeaning
nameOptional identifier used by globe.remove(name)
stagebeneath, above, or post
zPaint order inside the stage; lower values paint first
durationMilliseconds for one cycle; default 1000
holdMilliseconds held at the end of a cycle
loopWhether the effect repeats; default true
setup(globe)Runs once and returns private state
frame(ctx, globe, t, state)Paints the current frame, where t is from 0 to 1
dispose(state, globe)Cleans up listeners, timers, and other resources

Each frame runs inside its own ctx.save() and ctx.restore(). A thrown error is isolated and reported once so one custom effect does not stop the globe.

Paint stages

  • beneath paints before the globe and is suitable for backgrounds.
  • above paints after the globe and is the default for most overlays.
  • post paints last and is intended for full-frame processing.

Deterministic animation

Derive the complete visual result from t, the effect state, and fixed input data. Do not call Math.random() on every frame. Use the seeded rng() and particles() helpers instead.

import { particles, rng, stagger } from "canvas-globe/fx";

const dots = particles(80, 42, (random) => ({
angle: random() * Math.PI * 2,
radius: 20 + random() * 80,
}));

seek(ms) and renderFrame(ms) can then recreate the same frame. Effects that intentionally accumulate prior frames should be exported in sequential order.

Geometry and drawing helpers

The authoring toolkit includes:

  • timing: linear, easeIn, easeOut, easeInOut, backOut, pingPong, clamp01, lerp, stagger
  • deterministic data: rng, particles
  • reusable canvases: scratch, releaseScratch
  • spherical geometry: destination, ring, centroid, drawPath
  • interface drawing: panel, label, readout, bar
  • pointer handling: onTap, onDragPath, nearest, pointInPath

The globe instance also provides project(), unproject(), tracePath(), landPoints(), and a read-only pointer state.

Cleanup rules

Anything created in setup() should be removed in dispose(). This includes DOM listeners, intervals, animation handles, scratch resources, and subscriptions. globe.remove(), clearEffects(), and destroy() all invoke the cleanup hook.

See the effects catalogue for production-ready examples.