The gallery holds two collections. The Canvas, Pixel buffer, WebGL and Text demos are short pieces of JavaScript written for this page in the spirit of the JS1k competition: no libraries, no assets, a few hundred bytes of code each. The JS1k and JS1024 chips hold real entries from those two competitions. Open any demo to run it full screen, then open the code panel to read or rewrite it. Edits run immediately and are kept in this browser until you revert them.
A demo is the body of a function. It receives the canvas and returns the function that draws one frame:
// arguments: a, b, w, h, M, U
var i = 0;
return function (t, dt) {
b.fillStyle = 'hsl(' + (t * 60) + ',90%,60%)';
b.fillRect(w / 2 - 20, h / 2 - 20, 40, 40);
};
| a | the canvas element |
| b | its 2D context, already scaled so you can draw in CSS pixels (null for WebGL demos) |
| w, h | drawing area in CSS pixels |
| M | pointer: M.x, M.y, M.down — mouse, pen and touch alike |
| U | the shared helpers below |
| t, dt | seconds since the demo started, and seconds since the previous frame |
| U.buf(w,h) | off-screen pixel buffer: .u is a Uint32 view, .flush(b,w,h) scales it onto the canvas |
| U.rgb(r,g,b) | packs a colour for that Uint32 view (values are clamped) |
| U.hsl(h,s,l,a) | builds an hsl() / hsla() string |
| U.noise2(x,y) | smooth value noise, 0…1 |
| U.fbm(x,y,n) | n octaves of that noise |
| U.GL(a,frag,M) | compiles a fragment shader over a full-screen triangle and returns the draw function. Uniforms: u_t, u_r, u_m |
| U.rnd, U.lerp, U.clamp, U.TAU | the usual |
Search matches the name and the tags under it. The chips narrow the gallery to one kind of demo, and the sort menu reorders it: by name, by how many bytes the code takes, grouped by type, by contest year or by author. Sorting by size is the quickest way to see how little a moving picture actually costs. Previous and next inside a demo follow whatever order and filter the gallery is in.
← → previous and next demo, Esc back to the gallery,
Space pause, c code panel, f full screen,
r a random demo, / jump to search, h hide the controls so
the picture fills the screen. A contest entry keeps the keyboard for itself once you click into
it; Esc still brings you back.
The gallery only animates the previews near the viewport, a few at a time, at a reduced frame rate; everything else holds a still frame. Turn off Animate previews for a completely static gallery. Inside a demo, drop the resolution to Half if a phone starts to struggle — the pixel-buffer and WebGL demos are the expensive ones.
Some demos make sound — search for sound to list them, or look for (with sound) on the card. Tick Sound on to hear them; it starts off, since browsers only allow audio after you have interacted with the page. Every note is derived from whatever the demo is already computing: the mode frequency of a drumhead, the Doppler shift of a passing siren, the impact speed of two billiard balls.
The JS1k chip holds all 1491 entries saved from js1k.com (2010 to 2019): every entry on the overview pages of the eleven editions, plus 53 earlier 2010 submissions the site still serves but no longer lists. The JS1024 chip holds all 220 entries from js1024.fun (2020 to 2026). Each one runs in its own frame inside the same page code the contest site wrapped around it, so the code is exactly what its author submitted and the size on the card is the one the contest recorded.
Contest entries handle their own keyboard and mouse: click into the picture before you play. Pause, Restart, Save PNG and Sound on work as they do everywhere else. The resolution menu does not apply, because each entry sizes its own canvas when it starts; press Restart after resizing the window. The code panel shows the author’s description, any notes they left, and links to the entry on the contest site.
With Animate previews on, contest entries on screen run in their cards too, muted, slowed to about a dozen frames a second, and without mouse, keyboard or pop-ups. Each needs a whole page of its own, so at most twenty run at once (six on a phone), enough for a full screen of cards. New ones start when scrolling stops, and a card that has run keeps its last frame, as the rest of the gallery does.
The JS1024 p5.js entries run on a copy of p5.js 1.4.0 kept inside this file (p5.js is LGPL-licensed). A few entries loaded an image from the contest server when they were new and draw without it here, and some 2010 entries depend on browser behaviour that has changed since.
The Canvas, Pixel buffer, WebGL and Text demos are original code written for this page, modelled on the classic size-coding effects: plasma, tunnel, metaballs, fire, attractors, raymarching. The contest entries belong to their authors, who are credited on every card and in the code panel; both contest sites ask that entries not be copied without the author’s consent.