Demo
Type a message, watch it light up
The wall paints letters one bulb at a time. Three built-in themes — original Stranger Things, classic Christmas, Fourth of July — show how the plugin adapts.
joycelights
type a message — the wall spells it for you, one bulb at a time
Install & usage
Drop it in
One stylesheet, one script. No framework, no build step.
<link rel="stylesheet" href="path/to/joycelights.css">
<script src="path/to/joycelights.js"></script>
<div id="wall"></div>
<script>
const wall = new JoyceLights('#wall');
wall.spell('RIGHT HERE');
</script>
Themes
Built-in and custom
Swap themes at runtime with setOptions. The built-ins (christmas, july4) ship as counter-examples so the API doesn't end up shrink-wrapped to one aesthetic.
wall.setOptions({
theme: 'christmas',
palette: ['red', 'green'],
drips: false,
letterTilt: 0, letterShift: 0, letterScale: false,
});
wall.setOptions({
theme: 'july4',
palette: ['red', 'white', 'blue'],
drips: false, randomColors: true,
letterTilt: 0, letterShift: 0, letterScale: false,
});
Palette colors: red · green · blue · yellow · orange · white. For a custom theme, add a modifier class (.joycelights--mygame) and override the CSS variables — see Theming below.
Full-bleed wallpaper
Promote the wallpaper from the wall element to the surrounding container so a whole section reads as one canvas:
<header class="stage joycelights--july4">
<h1>Independence Day</h1>
<div id="wall"></div>
</header>
<style>
.stage {
background-color: var(--joycelights-wallpaper-base);
background-image: var(--joycelights-wallpaper-image);
background-repeat: repeat;
background-size: 160px 160px;
}
</style>
<script>
new JoyceLights('#wall', { flat: true });
</script>
API
Options & methods
Everything's configurable — rows, palette, per-letter colors, timing, flicker, drips, theme. Methods cover the typical lifecycle plus a few extras.
Options
new JoyceLights('#wall', {
rows: ['ABCDEFGH', 'IJKLMNOPQ', 'RSTUVWXYZ'],
palette: ['red', 'green', 'blue', 'yellow', 'orange'],
colorMap: { H: 'red', E: 'red', L: 'red', O: 'red' },
randomColors: false,
flicker: true,
speed: 600,
onTimeRatio: 0.7,
drips: true,
wallpaper: true,
flat: false,
theme: null, // 'christmas' | 'july4' | null
letterTilt: 14,
letterShift: 6,
letterScale: true,
wireSag: 10,
onLetter: (letter, color, index) => { /* sfx, etc. */ },
});
Methods
wall.spell('HELLO');
wall.spell('RUN', { speed: 900 });
wall.light('A', 'red');
wall.unlight('A');
wall.clear();
wall.cancel();
wall.setOptions({ theme: 'july4' });
wall.destroy();
Theming
CSS custom properties
The wall, the paint-drip letters, the wallpaper, and the bulbs all read from CSS variables. Override them in a modifier class to roll your own theme.
.joycelights {
--joycelights-paint: #1a1612;
--joycelights-wallpaper-base: #dec59b;
--joycelights-wallpaper-image: url("…SVG data URI…");
--joycelights-wire: #1a2a14;
--joycelights-letter-font: 'Permanent Marker', cursive;
--joycelights-letter-shadow: 0 1px 0 rgba(0,0,0,0.5), 1px 0 0 rgba(0,0,0,0.3);
--joycelights-vignette: radial-gradient(/* … */);
--joycelights-shadow: inset 0 0 60px rgba(60,30,10,0.35), 0 6px 30px rgba(0,0,0,0.6);
--joycelights-radius: 4px;
}
HTML, CSS, and a smidge of JavaScript — no framework, no build step.