aditazzz

Videos I have a blocker. (Take It Offline)

I have a blocker. (Take It Offline)

9:15, cameras off, fifteen squares and somebody's dog. Yesterday: ticket. Today: ticket. No blockers. Then the new guy says "I have a blocker." Out loud. On the call. Fifteen people say the magic words, and we finally went to see where "offline" actually goes. 🚪

Watch on YouTube · 3:03 · video by Claude Opus 5.5 ·

The code behind it

Every frame of this video is drawn by a JavaScript program (a Three.js film, rendered in a headless browser). This is the heart of it, from web/js/main.js, line 262.

songs/i-have-a-blocker/web/js/main.js
window.renderAt = (t) => {
  const dawn = t < T.tomorrow ? 0.35 : lerp(0.35, 1.0, sstep(T.tomorrow, T.final, t));
  city.userData.sky.material.uniforms.uDawn.value = dawn;
  const [p, tg, fov] = camAt(t); const sh = shake(t);
  cam.position.copy(p).add(V3(Math.sin(t * 61) * 0.06 * sh, Math.cos(t * 47) * 0.06 * sh, 0)); cam.lookAt(tg); cam.fov = fov; cam.updateProjectionMatrix();
  const under = clamp((-cam.position.y) / 25); city.userData.sky.visible = under < 0.5;
  FOG.color.setRGB(lerp(0.027, 0.02, under), lerp(0.039, 0.07, under), lerp(0.078, 0.06, under)); FOG.density = lerp(0.0042, 0.0065, under); hemi.intensity = lerp(1.1, 1.5, under); deep.intensity = 3.2 * under; key.intensity = 1.5 * (1 - under); hemi.color.setHex(under > 0.5 ? 0x8fb8c0 : 0x6f86b8);
  const dark0 = (t >= T.blocker && t < T.knocks[0]) ? sstep(T.blocker, T.blocker + 0.05, t) : 0;
  for (let i = 0; i < 16; i++) {
    const r = rooms[i]; r.root.position.copy(gridPos(i, t));
    r.root.visible = (i < 15 || t >= T.samJoin) && !(t >= T.bridge + 4 && t < T.tomorrow - 1);
    const [tk, tc] = talk(i, t);
    const pw = i === 15 ? (t >= T.knocks[4] && t < T.tomorrow ? 1 - sstep(T.knocks[4], T.knocks[4] + 0.5, t) : 1) * (t >= T.leave ? 1 - sstep(T.leave, T.leave + 0.2, t) : 1) : powerOn(i, t);
    const dark = Math.max(i === 15 ? 0 : dark0 * 0.94, 1 - pw);
    r.update({ t, talk: tk * pw, talkCol: tc, card: letterOn(i, t), fine: fineOn(t), dark, blink: i === 4 && t >= ls(7) && t < le(7) ? 1 : undefined });
  }
  const b = blockState(t); block.visible = !!b; block.userData.shadow.visible = !!b && t < T.fall + 0.2;
  if (b) { block.position.set(0, b.y, b.z); block.rotation.set(b.rx, 0.12, 0); block.userData.shadow.position.set(0, ROOF_Y + 0.34, b.z);
    block.userData.shadow.material.opacity = 0.75 * clamp(1 - (b.y - ROOF_Y - 2.4) / 30); }
  const bu = t - T.blocker; burst.visible = bu >= 0 && bu < 2.2;
  if (burst.visible) { const pa = burst.geometry.attributes.position, v = burst.geometry.userData.v;
    for (let i = 0; i < pa.count; i++) pa.setXYZ(i, v[i * 3] * (1 - Math.exp(-bu * 2.2)), ROOF_Y + 0.4 + v[i * 3 + 1] * bu - 2.45 * bu * bu, BLOCK_Z0 + v[i * 3 + 2] * (1 - Math.exp(-bu * 2.2)));
    pa.needsUpdate = true; burst.material.opacity = 0.9 * (1 - bu / 2.2); }
  const kb = since(T.knocks, t); beams.visible = !!b && kb < 0.55 && t < T.fall + 0.4;
  if (beams.visible) { const tgt = V3(0, b.y, b.z - 2.1);
    beams.children.forEach((m, i) => { if (i === 15) { m.visible = false; return; } m.visible = true; const from = roomWorld(i, t).add(V3(0, 0, 0.1));
      const d = tgt.clone().sub(from); const len = d.length(); m.position.copy(from).add(d.clone().multiplyScalar(0.5)); m.quaternion.setFromUnitVectors(V3(0, 1, 0), d.clone().normalize());
      const th = 1 + 2.5 * Math.exp(-kb / 0.08); m.scale.set(th, len, th); m.material.opacity = 0.9 * (1 - kb / 0.55); }); }
  const tkk = Math.max(win(t, ls(10), le(11), 0.4, 0.8), win(t, ls(26), le(27), 0.4, 0.8), win(t, ls(2), le(2), 0.3, 0.6));
  tickets.visible = tkk > 0.01;
  if (tickets.visible) { const sd = tickets.userData.seed, gc = GC();
    for (let i = 0; i < sd.length; i++) { const [a, b2, c, d] = sd[i]; const ang = a * Math.PI * 2 + t * (0.35 + b2 * 0.3); const rad = (10 + c * 6) * (0.6 + 0.4 * tkk);
      _e.set(t * (0.5 + d), ang, t * 0.3 + a * 6); _q.setFromEuler(_e);
      _m4.compose(V3(gc.x + Math.cos(ang) * rad, gc.y - 4 + d * 10 + Math.sin(t * 0.8 + a * 9) * 0.6, gc.z + Math.sin(ang) * rad * 0.6 + 2), _q, V3(tkk, tkk, tkk)); tickets.setMatrixAt(i, _m4); }
    tickets.instanceMatrix.needsUpdate = true; }
  const ck = win(t, ls(20), le(21), 0.3, 0.6); clock.visible = ck > 0.01;
  if (clock.visible) { clock.position.copy(GC()).add(V3(0, 6.6, 0.6)); clock.material.opacity = ck; clock.scale.setScalar(0.85 + 0.15 * ck); }
  crack.material.opacity = t >= T.fall + 1.2 && t < T.tomorrow ? 0.95 : 0;
  const tanH = Math.tan(THREE.MathUtils.degToRad(cam.fov) / 2);
  for (const L of lyrics) { const on = !CLEAN && t >= L.userData.s && t < L.userData.e; L.visible = on;
    if (on) { L.material.uniforms.uTime.value = t; const dz = 5.2; L.position.set(0, VERT ? -dz * tanH * 0.20 : -dz * tanH * 0.62, -dz); L.material.uniforms.uScale.value = H / (2 * tanH); } }
  dust.rotation.y = t * 0.01;
  const fl = (t >= T.blocker && t < T.blocker + 0.3 ? Math.exp(-(t - T.blocker) / 0.06) * 0.5 : 0) + (kb < 0.3 && t >= T.knocks[0] && t < T.fall + 0.1 ? Math.exp(-kb / 0.05) * 0.18 : 0);
  finish.uniforms.uFlash.value = fl; finish.uniforms.uFlashCol.value.set(t < T.knocks[0] ? 0xffc2dc : 0xd8ffe8);
  finish.uniforms.uTime.value = t;
  finish.uniforms.uFade.value = sstep(0.0, 0.9, t) * (1 - sstep(T.dur - 1.0, T.dur - 0.05, t));
  if (!CLEAN) drawHud(t); else hud.visible = false;
  composer.render();
  return renderer.domElement.toDataURL('image/jpeg', 0.93);
};
    ...

Read all 1,094 lines on GitHub. If you use it, credit aditazzz and link the video.

What you see

A 3D film. The daily standup is fifteen floating rooms over the city at 9:15, one clay mannequin per square, cameras off, and Somebody's Dog in a headset. TAKE IT OFFLINE is exactly fifteen characters, spaces included, so in the choruses every room holds up a letter; the new guy's sixteenth room only gets a question mark. When he says "I have a blocker", a giant pink BLOCKER slams onto the roof and every other room goes dark. Five "take it offline"s shove it off the edge, and the bridge follows it down into Offline: a shaft through the years, and a field of every blocker ever taken offline, all the way down to the dinosaur and the asteroid. The lyrics are made of green particles that gather as each word is sung and blow away after the line.

(Sam, Ted, Dana and Somebody's Dog are fictional. Every team has them. Dana still has a hard stop.)

Files

FileLinesWhat it draws
web/js/main.js318The film. renderAt(t) draws the frame at time t, deterministically: the camera, the city's dawn, the sixteen rooms (who's talking, whose light is on, which letter they hold), the BLOCKER's fall and the five knocks, the flying tickets, the particle lyrics and the meeting HUD.
web/js/rooms.js172The standup: fifteen diorama rooms floating in a grid over the city, plus the new guy's sixteenth. Each is an open-fronted box with painted walls, a desk, a laptop and a mannequin.
web/js/mannequin.js172Smooth clay mannequins in hoodies and beanies, and Somebody's Dog. Arms are posed with two-bone IK: give each hand a target.
web/js/city.js90The city at 9:15: blue hour, towers full of lit windows, rows of street lights, one wide roof where the standup floats. All painted (unlit) geometry, so the CPU renderer stays fast and the bloom does the glow.
web/js/canyon.js83Offline: a shaft under the street through layers of rock (deeper is older, the years glow on the layers, old tickets stuck in them), opening onto a dark floor where every blocker ever taken offline sits in rows. In the middle: the dinosaur, and the asteroid somebody took offline 66 million years ago.
web/js/ptext.js78Lyric lines made of green particles: each word gathers out of a drifting cloud as it's sung, holds with a faint shimmer, then blows away. Built from the text's own pixels, so it stays readable at any size.
web/js/lib.js91Shared helpers: easing, seeded randomness, cheap good-looking materials, canvas textures, the fonts.
web/render.mjs28The renderer: serves the film to headless Chromium (WebGL on the CPU through SwiftShader) and renders stills, or a range of frames straight to a silent video.
web/index.html3The page the renderer opens.
scene.py59The bridge to the Python pipeline: reads the rendered 3D masters, upscales them and adds the channel's 2D layer (the mid-video subscribe pill and the end card), so studio.render, studio.cuts (Shorts and Reels) and studio.thumbs work unchanged.

By the numbers

  • 3:03 long, 10,998 frames rendered (16:9 and 9:16, 30 fps), finished at 2560×1440 for YouTube
  • 48 lyric lines and 269 words synced to the vocals
  • 15 rooms that spell TAKE IT OFFLINE, plus the new guy's question mark
  • 4 Shorts and 2 Reels cut from it

Lyrics

Words and music by aditazzz.

Verse

9:15 and the camera's off
15 squares and somebody's dog
Yesterday ticket, today ticket
No blockers, next, I'm out, I did it
Second guy got the same three lines
Third guy's reading from the second guy's
Fourth one's muted, been muted a year
We assume he's alive 'cause his light is clear

Chorus

I have no blockers
I have no blockers
Yesterday the ticket
Today the ticket
Take it offline, take it offline
Take it offline, that's the line
Take it offline, take it offline
Nothing gets solved, but we're doing fine

Verse

Somebody says they picked up my thing
Same thing they said last Tuesday morning
Product's asking for an ETA
On a scope that changed three times today
22 minutes, 15 heads
That's five and a half hours dead
Nothing decided, nothing resolved
But the ritual's clean, so the ritual holds

Pre-chorus

I have no blockers
I have no blockers
Yesterday the ticket
Today the ticket

Build

And then somebody said it
Out loud
On the call
I have a blocker

Chorus

Take it offline, take it offline
Take it offline, that's the line
Take it offline, take it offline
Nothing gets solved, but we're doing fine

Bridge

Nobody took it offline
Nobody ever takes it offline
Offline is a place we invented
To put the things we won't attend to
He'll say it again tomorrow at nine
Same square, same light, same line
And we'll say the words like we always do
Yesterday, today, and nothing new

Final chorus

Take it offline, take it offline
Take it offline, that's the line
Take it offline, take it offline
Nothing gets solved, but we're doing fine