Chromatic Split Glow
- Source
- arlan.me/vault ↗
- Author
- Arlan
- Licence
- MIT
Loading…
The word chrome glowing on a dark card with a shifting rainbow chromatic-aberration split that follows the cursor.
Code
"use client";
import { approach, drawBlurred, useStage, type Scene } from "./stage";
/*
* "chrome" glowing on a dark card, split into a shifting rainbow of offset
* copies that add back to white at the core. The split follows the cursor;
* left alone, it drifts in a slow orbit.
*/
const HUES = 7;
function createScene(): Scene {
const aim = { x: 0, y: 0 };
return {
frame({ ctx, w, h, t, dt, p }) {
ctx.fillStyle = "#1c2133";
ctx.fillRect(0, 0, w, h);
const cx = w / 2;
const cy = h / 2;
const size = Math.min(h * 0.36, w * 0.21);
// aim: from the word toward the pointer, or an idle orbit
const tx = p.inside ? (p.x - cx) / w : Math.cos(t * 0.6) * 0.45;
const ty = p.inside ? (p.y - cy) / h : Math.sin(t * 0.8) * 0.3;
aim.x = dt === 0 ? tx : approach(aim.x, tx, 5, dt);
aim.y = dt === 0 ? ty : approach(aim.y, ty, 5, dt);
const spread = size * 0.16;
ctx.font = `800 ${size}px "Helvetica Neue", Inter, "Segoe UI", Arial, sans-serif`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const paint = (x: number, y: number) => (c: CanvasRenderingContext2D) => {
c.fillStyle = "#000";
c.fillText("chrome", x, y);
};
// soft glow behind
ctx.globalAlpha = 0.55;
drawBlurred(ctx, size * 0.5, "#6d7cff", paint(cx, cy));
ctx.globalAlpha = 0.35;
drawBlurred(ctx, size * 0.18, "#c7d0ff", paint(cx, cy));
ctx.globalAlpha = 1;
// rainbow split, additive
ctx.globalCompositeOperation = "lighter";
const shift = t * 40;
for (let i = 0; i < HUES; i++) {
const k = i / (HUES - 1) - 0.5;
const hue = (shift + i * (300 / (HUES - 1))) % 360;
const ox = aim.x * spread * 10 * k;
const oy = aim.y * spread * 10 * k;
ctx.fillStyle = `hsla(${hue},100%,56%,0.3)`;
ctx.fillText("chrome", cx + ox, cy + oy);
ctx.globalAlpha = 0.35;
drawBlurred(ctx, size * 0.06, `hsl(${hue},100%,60%)`, paint(cx + ox, cy + oy));
ctx.globalAlpha = 1;
}
// white-hot core
ctx.fillStyle = "rgba(255,255,255,0.12)";
ctx.fillText("chrome", cx, cy);
ctx.globalCompositeOperation = "source-over";
},
};
}
export default function ChromaSplit() {
const ref = useStage(createScene, 1);
return <div ref={ref} className="relative h-full w-full overflow-hidden bg-[#1c2133]" />;
}
Prompt
Build "Chromatic Split Glow", a text animation. What it does: The word chrome glowing on a dark card with a shifting rainbow chromatic-aberration split that follows the cursor. Write it as a single self-contained React component in TypeScript that fills its parent (w-full h-full), styled with Tailwind CSS. Technique: an HTML canvas, a requestAnimationFrame loop, pointer tracking. It sits on a dark background, in a 16:10 frame. Respect prefers-reduced-motion with a still state, pause work when the element is off screen, and keep it accessible. Original: https://www.arlan.me/vault (Arlan, MIT).