bg-winter.jpg goes into public/. 3.4 MB. 3904×1088. Snow, icicles, kids with snowballs. A winter reading of the same Tokyo-adjacent panorama the spring layer covers. The spring layer has a radial alpha mask. Each pixel’s opacity is a function of its distance from the centre. The bass amplitude drives the hole radius. On a quiet part of the track, the spring image is fully opaque; that image is cherry-blossom petal light-trails over neon Tokyo. On the bass hit, a circular gap opens. Through it, winter.
That is the whole effect. One image file. One distance check per pixel. The rest was already in place.
The stack
Two panoramas share dimensions and position in the frame: bg-city.jpg on top, bg-winter.jpg underneath. Neither moves during playback. The only animation is the mask.
The mask is radial. The hole radius maps to the bass amplitude. At zero amplitude, radius is zero. The spring image is fully opaque; winter is invisible. At peak amplitude the radius grows, the spring image becomes transparent in a circular region, and winter shows through. The pixel operation is a distance calculation, distance(pixel, centre) < holeRadius, followed by a conditional alpha write. That is the entire portal mechanic.
No shader. No compositing pipeline. No additional render pass. The bass signal was already in the system, driving other effects. The winter image required a new file in public/ and a new layer at position zero in the composite stack. The mask logic sat on the existing spring layer.
The spring background
On 2026-06-21, the city background was swapped: bg-city.png out, bg-city.jpg in. 3.4 MB, 3904×1088, swirling cherry-blossom petal light-trails over neon Tokyo. The dimensions matched the previous file exactly, so BG_W/BG_H and all the parallax and grade maths needed no changes.
This matters for the portal. The spring panorama is the mask carrier. It needed to be wide enough to fill the frame at any zoom level and thematically distinct enough from winter to make the contrast legible. The cherry-blossom light-trails panorama satisfied both.
The portal lands
The temporal portal commit arrived on 2026-06-22. A second panorama went in behind the spring layer: public/bg-winter.jpg, 3.4 MB, 3904×1088. Snow, icicles, kids with snowballs. The spring layer got the radial alpha mask.
Keeping both panoramas at 3904×1088 was deliberate. A winter image at different dimensions would require scale transforms, repositioning, possibly separate parallax parameters. Same dimensions means the winter layer drops into position zero and the existing rendering path handles it without modification.
Later the same day, the winter panorama was replaced with a richer scene: 3.3 MB, same dimensions, snowball fight, snow-laden blossoms, neon skyline at sunset. No code change. File swap, rebuild. The mask, the radius calculation, the bass wiring: unchanged.
The halfway swap
At swapFrame = round(durationInFrames*0.5), the two panoramas trade roles.
A swapOpen bell curve runs ±50 frames around the midpoint. It drives holeR += swapOpen*1500, which blooms the hole radius to full width. At peak bloom, the layers exchange. What was on top goes underneath; what was underneath comes to the front. The portal flips direction.
For the first half of the track, bass opens a hole in spring and winter shows through. The midpoint flips it: bass opens a hole in winter, spring returns. The viewer has crossed seasons with no cut. No crossfade. No second video track.
Out of scope: a custom dissolve or dedicated transition effect around the swap point. The swapOpen bell expanding holeR already reads as a transition. Adding a crossfade on top of a bloom that opens and closes over 100 frames would be redundant.
Why not a shader
A fragment shader with a circular clip region would have given more control: feathered edges, chromatic aberration at the boundary, vignetting. The trade-off is integration cost.
The visualiser is Remotion-based. Compositing happens in React and canvas. A fragment shader needs a WebGL context. The radial alpha mask is a canvas globalCompositeOperation and a per-pixel distance check. No GLSL, no separate render pass, no GL context management.
The mask edge is hard. On fast bass transients, where the hole grows and contracts over 10–20 frames, soft-edge blur is likely imperceptible during playback and expensive to tune. Hard edge, fast motion: acceptable trade.
The centre rework
One more change from the same day: the screen-blend spotlight overlay at the portal centre was removed. The image itself became the glow.
The logic: an overlay competes with what’s beneath it. At the centre of the bass portal, where the hole is widest, the winter panorama is already doing the visual work: the snowball fight, the neon, the snow-laden blossoms. Putting a synthetic glow over the top diluted it.
Removing the overlay had a secondary consequence. At full bass amplitude, the centre of the portal renders the winter image with no additional compositing on top. The perceived glow is the image’s own palette: the neon Tokyo winter skyline, not a rendered effect.
The file-swap pattern
The winter panorama changed twice within the same day. Both swaps were dimension-preserving. The improvement cost one file change and a rebuild.
The code has no knowledge of which season is in bg-winter.jpg. It knows the file path, the dimensions, and the mask parameters. Seasonal identity lives in the JPEG. Swapping it without a code change is confirmation that the abstraction is holding: the mask logic is not coupled to the image content.
The opposite approach, hardcoding season-specific adjustments in the compositing logic, would have made the second swap a code change. Keeping the seasonal data in the file and the compositing logic in the code is the correct split. The portal is a rendering operation. The seasons are assets.
What the portal cost
The full implementation:
bg-winter.jpg: one JPEG, 3904×1088, dropped intopublic/- Radial alpha mask: one distance-from-centre calculation per pixel on the front layer
swapFrame: one frame variableswapOpenbell curve: a few lines drivingholeR += swapOpen*1500over ±50 frames- Bass amplitude → hole radius: already wired into the system
The bass signal was already in the system, and the spring panorama already sat full-width at position 1. Two additions to an existing pipeline, not a new pipeline.
“Temporal portal” sounds like a complex effect. The cost was a distance calculation and a JPEG.



