Agent skill · flornkm

webgl-components

Build small, always-on WebGL visuals (identity avatars, ambient orbs, glass and iridescent surfaces, animated textures) that ship inside a normal web app UI without wrecking performance, accessibility, SSR, or layout. Use whenever a shader-, GLSL-, or canvas-driven decorative element is added to a product UI, especially one rendered many times per page or per list; when reviewing or optimizing one; or when debugging one that renders blurry, aliased, all-black, or paints over the surrounding UI on machines without hardware acceleration.

What it needs

About 12k tokens when loaded.

What this skill does

WebGL Components Lessons for embedding shader-driven visuals (identity avatars, ambient orbs, animated textures) into product UI. The failure modes are predictable, and nearly all of them come from treating the widget like a demo instead of like a component that renders fifty times in a list. Architecture: one context, many instances Never create one WebGL context per component instance. Browsers cap a document at roughly 8 to 16 live contexts, then silently evict the oldest. A list of avatars hits that cap immediately. Keep one module-level WebGL context rendering offscreen, and give each component instance a cheap 2D canvas. Each frame: draw into the shared GL canvas, then blit the region into the instance's 2D canvas with drawImage. The GL drawing buffer is only valid until the browser composites, so draw and blit within the same task. Never across an await. GL's origin is bottom-left and the 2D canvas' is top-left, so blit from canvas.height - size, not from 0. Grow the shared canvas to fit the largest instance and never shrink it mid-session. Group identical draws. Instances agreeing on every visual input (source, tint, size, pointer state) paint identical pixels, so draw once and blit that result to all of their canvases. A list of same-styled items then costs one draw per frame instead of one per row. Frame loop discipline One requestAnimationFrame loop for all instances, owned at module level. No per-instance loops. Gate every instance on an IntersectionObserver so offscreen instances never draw. Pause the loop entirely when document.visibilityState !== "visible", and stop scheduling once nothing visible remains. Cap the frame rate. Slow ambient drift gains nothing above 30fps, and an uncapped loop pins a core for as long as the widgets are on screen, twice over on a 120Hz display where rAF fires at 120. Ration expensive one-time work. …

How to use it

Reference it in AdaL, Claude Code, Cursor or any coding agent — nothing to install:

@skills flornkm/webgl-components

View the source on GitHub

Browse the @skills marketplace