Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

🌌 GalaxyJS

The universe, one line of code.

A cosmic animation + UI component library with zero required dependencies. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Six of the 86 animations are three.js scenes. three.js is optional and lazily loaded: nothing is requested unless you mount one of those six, and if it cannot load they paint a still poster instead of an empty box.

CILicenseRequired dependenciesOptionalVersion

Live demo: https://edwson.github.io/GalaxyJS/ (mirror: https://edwson.com/GalaxyJS/) · Open index.html locally for the interactive playground.


✨ What's new in v3.4 "Optics"

Six new animations (80 → 86) and an optional three.js tier.

These six needed something the canvas and fragment-shader tiers genuinely cannot give: a scene graph, a real 3D volume, GPU-resident simulation state, or a multi-pass post-processing chain. So they declare renderer: "three", and the library loads three.js on demand, by dynamic import, the first time one of them mounts — once per page, shared across all six. A page that never uses one downloads nothing extra.

  • eventHorizon — a Schwarzschild black hole solved, not painted. Every pixel's photon is integrated through curved spacetime (d²u/dφ² = -u + 3/2·rs·u²), so the photon ring, the Einstein ring of the background stars, and the far side of the disk bent up over the top all fall out of the geodesics. The disk carries relativistic Doppler shift and beaming (I ∝ δ⁴) — the bright/dim asymmetry is physics, not a gradient.
  • molecularCloud — a genuine 128³ Data3DTexture raymarched in the volume's own local space, lit from within by an embedded protostar with Beer–Lambert extinction along a secondary shadow ray and a Henyey–Greenstein phase function. Rotating it gives real parallax and self-occlusion, which is exactly what a 2D noise field cannot do.
  • spiralForge — 340,000 stars in one draw call. Each orbit is integrated in the vertex shader against a flat rotation curve, so there is no per-frame CPU work at all; because ω varies with radius the density-wave arms shear over time. Colour comes from a blackbody locus driven by a mass–temperature relation, so rare hot O/B stars burn blue in the arms.
  • ringedWorld — a gas giant with Rayleigh single scattering (blue limb, warm reddened terminator) and mutual shadowing: the rings cast a real shadow onto the planet, carrying their own Cassini-division gaps as bright lines across the disk, and the planet casts a real shadow back onto the rings.
  • gravitySim — true GPGPU. Particle state lives in float render targets and never returns to the CPU; a kick–drift (symplectic leapfrog) integrator keeps the disks stable instead of unwinding. Two attractors on an eccentric Kepler orbit raise real tidal bridges and tails at every pericentre. The pointer becomes a third mass.
  • starGlare — a hand-rolled HDR chain (no addons): bright pass → progressive downsample/upsample bloom → anamorphic streak → lateral chromatic aberration → filmic tonemap. A star's glare blooms and flares as an occluder slides across it.
<divid="hole" style="height:70vh"></div><script>Galaxy.create('eventHorizon','#hole',{tilt: 0.42});</script>

Bring your own copy to skip the network entirely:

import*asTHREEfrom"three";Galaxy.useThree(THREE);// now nothing is fetchedGalaxy.create("spiralForge","#hero",{stars: 400000});

Galaxy.rendererOf(name) reports "2d", "webgl2" or "three" if you want to check before mounting.


v3.3 "Deep Field"

Twenty new animations (60 → 80) and a WebGL2 tier — with no new dependencies.

Canvas 2D is still the default renderer and the fallback. Eight of the new animations declare renderer: "webgl2" and a hand-written GLSL fragment shader; a shared registerShader helper gives them the same lifecycle every 2D animation already gets — DPR-clamped resize, pointer input, off-screen suspension, and a single still frame under prefers-reduced-motion. Geometry is one full-screen triangle generated from gl_VertexID, so there is nothing to allocate and nothing to leak. If WebGL2 is unavailable the surface renders a 2D poster instead of an empty canvas.

  • Relativistic & gravitationallensing (Schwarzschild deflection and the Einstein ring), accretionDisk (Doppler beaming + gravitational redshift), nBody, tidalStream, inspiral
  • Volumetric & raymarched (WebGL2)volumetricNebula (Beer–Lambert absorption with a Henyey–Greenstein phase function), starSurface (granulation + limb darkening + prominences), atmosphere (Rayleigh + Mie scattering), dustLanes (self-shadowed dust), protoplanetary
  • Instrumentsspectrograph, transitCurve, waterfall, hrDiagram, pulsarTiming
  • Pointer-driven & generativegravityWell, nebulaPaint (an advecting, diffusing fluid you paint into), solarWind (bow shock + polar cusps), starForge, relativisticJets
<divid="deep" style="height:70vh"></div><script>Galaxy.create('volumetricNebula','#deep',{density: 1.2});</script>

✨ What's new in v3.2 "Cinematic"

  • Galaxy.scrollScene() — bind page scroll to a crossfading sequence of scenes. One call turns a sticky stage into a scroll-scrubbed cinematic, with an onProgress(p, index, scene) hook for your own HUD. Only the visible pair runs (battery-friendly), and reduced-motion shows one static frame. The showcase hero is built with it — see below.

✨ What's new in v3 "Nova"

  • One unified APIGalaxy.create(type, target, options) for every animation.
  • 86 animations — starfield, warp, black hole, nebula, spiral galaxy, meteors, constellation, particle field, aurora, wormhole, orbits, pulsar, mesh gradient, fireflies, matrix rain, plasma, fireworks, snow, waves, DNA helix, lightning, ripples, comets, confetti, bubbles, fog, synthwave grid, rain, vortex, sparkle, neon tunnel, swarm, ribbons, flow field, dotted globe, heartbeat, equalizer, clock, light rays, radar, embers, typewriter, spirograph, and 17 new in v3.1 — supernova, quasar, star cluster, cosmic web, eclipse, solar corona, galaxy merge, crystal lattice, moiré, starburst, nebula pillars, ion storm, stardust, orrery, oscilloscope, bokeh, magnetosphere, and 20 new in v3.3 — lensing, accretion disk, n-body, tidal stream, inspiral, volumetric nebula, star surface, atmosphere, dust lanes, protoplanetary disk, spectrograph, transit curve, radio waterfall, H-R diagram, pulsar timing, gravity well, nebula paint, solar wind, star forge, relativistic jets, and 6 new in v3.4 on the optional three.js tier — event horizon, molecular cloud, spiral forge, ringed world, gravity sim, star glare.
  • A real UI kit — buttons, cards, modals, toasts, tooltips, tabs, accordions, dropdowns, inputs, switches, progress, spinners — all driven by design tokens.
  • Theming — light/dark out of the box, fully tokenized via CSS variables and Galaxy.theme().
  • Accessible & efficient — respects prefers-reduced-motion, one shared rAF loop for the whole page, auto-pause off-screen, HiDPI-aware.
  • Declarative or imperative — wire everything with data- attributes, or script it.

🚀 Quick start

<linkrel="stylesheet" href="galaxy.css" /><scriptsrc="galaxy.js"></script><divid="hero" style="height: 60vh"></div><script>Galaxy.create("nebula","#hero",{speed: 1.2,colors: ["#7c5cff","#22d3ee","#f472b6"],});</script>

Or go fully declarative — no JS needed:

<divdata-galaxy="warp" data-galaxy-speed="1.5" style="height: 400px"></div>

CDN

<linkrel="stylesheet" href="https://unpkg.com/galaxyjs@3/galaxy.min.css" /><scriptsrc="https://unpkg.com/galaxyjs@3/galaxy.min.js"></script>

npm

npm install galaxyjs
importGalaxyfrom"galaxyjs";import"galaxyjs/galaxy.css";

🪐 Animations

constbg=Galaxy.create("blackHole","#stage",{radius: 0.2,speed: 1.4});bg.update({speed: 0.6});// live-tweakbg.pause();// pause / resume / destroy
starfield · warp · blackHole · nebula · spiral · meteors · constellation · particles · aurora · wormhole · orbits · pulsar · gradient · fireflies · matrix · plasma · fireworks · snow · waves · dna · lightning · ripples · comets · confetti · bubbles · fog · grid · rain · vortex · sparkle · tunnel · swarm · ribbons · flowfield · globe · heartbeat · equalizer · clock · rays · radar · embers · typewriter · spirograph · supernova · quasar · starcluster · cosmicWeb · eclipse · corona · galaxyMerge · lattice · moire · starburst · pillars · ionstorm · stardust · orrery · oscilloscope · bokeh · magnetosphere

Every instance returns a controller with start / stop / pause / resume / update / options / destroy. See docs/API.md for every option.

Add your own:

Galaxy.register("rain",{defaults: {count: 200},setup(host){/* ... */}});

🎬 Cinematic scroll scenes (v3.2)

Bind page scroll to a crossfading sequence of scenes — the whole hero in one call:

<sectionid="cine" style="height: 360vh;"><!-- the scroll "track" (gives you room) --><divstyle="position: sticky; top: 0; height: 100vh;"><divid="stage" style="position:absolute; inset:0;"></div><!-- your own HUD/headline overlay here --></div></section>
Galaxy.scrollScene("#stage",{scenes: ["galaxyMerge","quasar","supernova","magnetosphere"],track: "#cine",reducedScene: 0,// which single frame to show when motion is offonProgress(p,index,scene){// p is 0..1 across the whole sequence; index is the active scene.// Drive your own headline, telemetry, scrubber, etc.}});
  • Pass scenes as "name" or { type: "name", options: { speed: 1.2 } }.
  • Only the ≤2 crossfading scenes are mounted at a time, so the engine pauses everything else — no rAF fighting across a long sequence.
  • Under prefers-reduced-motion, it renders one static frame (reducedScene) and still fires onProgress once so your copy is correct.
  • Returns { progress(), layers, destroy() }. Call destroy() to unbind on teardown.

🧩 UI components

Galaxy.toast("Saved to your galaxy ✨",{type: "success"});Galaxy.modal({title: "Welcome 🚀",body: "Built with one call.",actions: [{label: "Cancel",variant: "ghost"},{label: "Launch",variant: "primary",onClick: ()=>{}},],});constok=awaitGalaxy.confirm("Eject the pod?");

Tooltips, tabs, accordions and dropdowns are declarative — add the markup and Galaxy.autoInit() (called automatically) wires them up:

<buttonclass="gx-btn gx-btn--primary" data-gx-tooltip="Hello!">Hover me</button>

🎨 Theming

Galaxy.toggleTheme();// dark <-> lightGalaxy.theme({accent: "#ff5d8f"});// override any token
:root { --gx-accent:#ff5d8f; --gx-radius:18px; }

♿ Accessibility & performance

  • Honors prefers-reduced-motion (renders one static frame, no loop).
  • A single requestAnimationFrame drives every surface on the page.
  • Surfaces auto-pause when scrolled off-screen (IntersectionObserver).
  • Canvases render at devicePixelRatio for crisp edges; .destroy() cleans up everything.

🤖 Use it with AI / MCP

GalaxyJS ships a Model Context Protocol server and a compact machine-readable manifest, so an AI agent can discover and use every animation and component in one line — at minimal token cost.

  • galaxy.manifest.json — the full API as compact JSON (single source of truth).
  • llms.txt — a token-efficient guide AI tools read directly.
  • mcp/ — an MCP server exposing galaxy_quickstart, galaxy_list, galaxy_get, galaxy_snippet.

Add it to any MCP client (e.g. Claude Desktop):

{
"mcpServers": {
"galaxyjs": { "command": "npx", "args": ["-y", "galaxyjs-mcp"] }
}
}

Then ask: "Use GalaxyJS to add a nebula background to #hero" → the agent calls galaxy_snippet and returns ready-to-paste code. See mcp/README.md.


📁 Project layout

galaxy.js # the runtime (UMD: <script> / CommonJS / bundler)
galaxy.css # design tokens + components + animation surfaces
galaxy.d.ts # TypeScript definitions
galaxy.manifest.json # machine-readable API (single source of truth)
llms.txt # token-efficient guide for AI tools
index.html # interactive playground (open in any browser)
mcp/ # Model Context Protocol server
docs/API.md # full API reference

License

MIT © Ed Chen. See LICENSE.

About

A zero-dependency cosmic animation + UI component library. Beautiful canvas backdrops, a themeable UI kit, and a single unified API — no build step, no framework, ~20 kB gzipped.

Resources

Code of conduct

Contributing

Security policy

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages