{"id":"lens-flare","version":"1.0.0","title":"Cinematic Lens Flare","summary":"A cinematic lens flare drawn over any frame: glow, starburst, anamorphic streak, rainbow halo and ghosts that move with the light.","kind":"effect","target":"canvas2d","collections":["backgrounds","product-reveals","hypnotic-loops"],"tags":["lens flare","flare","anamorphic","light leak","starburst","sun","glow","cinematic","overlay","golden hour"],"loopable":true,"motion":"procedural","durationSeconds":8,"status":"published","media":{"poster":"https://aipixelwizard.com/media/lens-flare/1.0.0/poster.webp","preview":"https://aipixelwizard.com/media/lens-flare/1.0.0/preview.mp4","sample":"https://aipixelwizard.com/media/lens-flare/1.0.0/sample.mp4","sampleBytes":1386482,"sampleNote":"Pre-rendered with the default settings. Customised settings must be exported locally (npm run render)."},"urls":{"page":"https://aipixelwizard.com/visuals/lens-flare","manifest":"https://aipixelwizard.com/api/v1/visuals/lens-flare/versions/1.0.0","agentMd":"https://aipixelwizard.com/registry/lens-flare/1.0.0/agent.md","files":"https://aipixelwizard.com/registry/lens-flare/1.0.0/","demo":"https://aipixelwizard.com/registry/lens-flare/1.0.0/index.html"},"description":"A lens flare as a finishing layer. Place a light anywhere in the frame (or just outside it) and the flare follows: a bright core and glow, a starburst from the aperture blades, an anamorphic streak, a rainbow halo, a chain of ghosts reflected through the centre of the frame, lens dirt that lights up near the source and a veil of glare. Four styles (cinematic, anamorphic blue streak, sun, soft), any light colour, and a light that drifts on a loop, sweeps across or stays put. On black it is ready to drop on a clip with Screen blending.","role":"Full-frame finishing effect (Canvas 2D): a lens flare layered over a scene.","useCases":["A golden-hour or hero shot finish","A light sweep across a title or product","A flare overlay for editors (on black, Screen blend)"],"synonyms":["j j abrams flare","anamorphic streak","sun flare","light flare","camera flare","flare overlay","optical flare","lens glare","sun burst"],"digest":"b2385edbafe5221be26b053fe7e9bf0516e74fc04545a44c04ecab653c82a347","implementation":{"target":"canvas2d","runtime":"browser","language":"javascript","module":"esm","entry":"src/lens-flare.js","exports":[{"name":"createLensFlare","signature":"createLensFlare({ style?, tint?, ghosts?, rays?, size?, dirt?, grain?, seed? }) => { style, draw(ctx, { x, y, width, height, intensity? }) }","description":"Draws the flare over whatever is on the canvas, for a light at (x, y) in pixels. Uses additive blending: draw it last."},{"name":"lightPath","signature":"lightPath(progress, kind = 'drift') => { x, y }","description":"Light position in fractions of the frame: 'drift' (a figure-of-eight that loops exactly), 'sweep' (left to right) or 'static'."},{"name":"STYLES","signature":"STYLES: Record<'cinematic' | 'anamorphic' | 'sun' | 'soft', object>","description":"Which flare elements each style uses and how strong they are."}],"reusable":["src/lens-flare.js"],"demo":"demo.js","harness":"index.html"},"dependencies":[{"id":"apw-runtime","version":"1.0.0","scope":"demo","reason":"Demo harness."}],"uses":[],"usedBy":[],"params":[{"key":"style","label":"Flare style","type":"select","default":"cinematic","options":[{"value":"cinematic","label":"Cinematic"},{"value":"anamorphic","label":"Anamorphic streak"},{"value":"sun","label":"Sun burst"},{"value":"soft","label":"Soft glow"}]},{"key":"tint","label":"Light colour","type":"color","default":"#ffd29a"},{"key":"path","label":"Light movement","help":"Drift loops seamlessly; Sweep crosses the frame once.","type":"select","default":"drift","options":[{"value":"drift","label":"Drift (loops)"},{"value":"sweep","label":"Sweep across"},{"value":"static","label":"Still"}]},{"key":"scene","label":"Backdrop","help":"Black is for laying the flare over your own footage with Screen blending.","type":"select","default":"dusk","options":[{"value":"dusk","label":"Golden hour hills"},{"value":"space","label":"Night sky"},{"value":"black","label":"Black (for Screen blending)"}]},{"key":"intensity","label":"Brightness","type":"number","min":0.3,"max":1.5,"step":0.05,"default":1},{"key":"size","label":"Size","type":"number","min":0.5,"max":1.6,"step":0.05,"default":1},{"key":"ghosts","label":"Ghosts","help":"Reflections along the line through the centre of the frame.","type":"integer","min":0,"max":12,"step":1,"default":7},{"key":"rays","label":"Starburst rays","type":"integer","min":6,"max":24,"step":2,"default":12},{"key":"dirt","label":"Lens dirt","type":"number","min":0,"max":1,"step":0.05,"default":0.5},{"key":"seed","label":"Variation","type":"integer","min":1,"max":9999,"step":1,"default":7}],"presets":[{"id":"default","label":"Golden hour","params":{}},{"id":"anamorphic","label":"Anamorphic night","params":{"style":"anamorphic","tint":"#bfe0ff","scene":"space","ghosts":6}},{"id":"sun-overlay","label":"Sun burst on black","params":{"style":"sun","tint":"#fff1d6","scene":"black","path":"static","rays":16}},{"id":"dream","label":"Soft rose glow","params":{"style":"soft","tint":"#ffb3c4","ghosts":9,"seed":21}}],"output":{"width":1080,"height":1080,"fps":30,"durationSeconds":8,"posterSeconds":1.4,"alpha":false,"motion":"procedural","loop":{"seamless":true,"cycleSeconds":8,"method":"With Drift (the default) the light follows a closed figure-of-eight with whole-number frequencies, and the flare is a pure function of the light position, so the last frame meets the first. Sweep and Still do not loop."},"seed":{"param":"seed","behavior":"Seed shapes the ghosts (where, how big, what colour), the starburst rays and the lens dirt. Same seed, same flare."}},"composition":{"inputs":"A canvas with your scene already drawn, and the light position in pixels (it may be off-frame).","outputs":"Adds light onto the canvas ('lighter' compositing) plus a faint dither grain over the frame.","coordinates":"Pixels of the canvas you draw on; ghosts mirror the light through the canvas centre.","lighting":"Additive; on black the result can be blended over footage with Screen or Add.","timing":"draw() is a pure function of the light position; lightPath(progress) gives a position per frame.","compatibleWith":["gradient-background","kinetic-title","particle-tunnel","number-reveal"],"notes":["To flare a 3D scene, project your light's 3D position to the screen (vector.project(camera)) and draw onto a 2D canvas laid over the WebGL one.","Fade intensity down when the light is hidden behind something."]},"reuse":["Title reveal: sweep the light behind Kinetic Title Reveal for a cinematic title card.","Overlay for footage: render it on black and blend it over a clip with Screen in any editor.","Product hero: pin the light to a product's highlight in a 3D scene by projecting its position each frame."],"integration":{"newProject":"Draw your background on a canvas, then call createLensFlare().draw(ctx, { x, y, width, height }) every frame, with x and y from lightPath(frame / totalFrames).","existingProject":"Copy src/lens-flare.js. After your scene is drawn each frame, draw the flare onto a 2D canvas over it at the light's screen position."},"performance":{"notes":"About 120 gradient fills per frame plus one full-frame dirt mask; light work at 1080p.","limits":"The dirt buffer is a full-size offscreen canvas; pass dirt: 0 to skip it on low memory devices."},"limitations":["A drawn approximation of a lens, not optical ray tracing: ghosts follow the classic axis through the frame centre.","It does not detect occlusion: lower intensity yourself when the light goes behind something."],"license":{"spdx":"MIT","notice":"Copyright (c) 2026 AI Pixel Wizard. Released under the MIT License. See LICENSE in this folder.","thirdParty":[]},"rights":{"approvedForPublicRelease":true},"provenance":"Adapted from the owner's threejs-sketches/light-atmosphere/webgpu-lens-flare (MIT), rebuilt for AI Pixel Wizard in October 2026 as a Canvas 2D finishing layer (no WebGPU needed) with flare styles, lens dirt, dithering and the frame/time contract.","changelog":[{"version":"1.0.0","date":"2026-10-05","notes":"Initial release."}],"verification":{"testedOn":"2026-10-05","inputs":{"lens-flare@1.0.0":"b2385edbafe5221be26b053fe7e9bf0516e74fc04545a44c04ecab653c82a347","apw-runtime@1.0.0":"5be859cdac74823ba0bcc32c6daf06688a871104d24db5d4ceaffffd84d7c40d"},"environment":"Chrome 154.0.8037.97 headless on Linux 7.0.0-38-generic (x64), Node 22.14.0","renderer":"Canvas 2D","width":1080,"height":1080,"fps":30,"frames":240,"renderSeconds":152.5,"loopCheck":{"checked":true,"seamless":true,"maxDifference":0,"note":"Frame 0 vs end state (progress 1): mean |Δ| 0.0000, max |Δ| 0 of 255."},"determinism":{"checked":true,"identical":true},"errors":[],"media":{"poster":"/media/lens-flare/1.0.0/poster.webp","preview":"/media/lens-flare/1.0.0/preview.mp4","sample":"/media/lens-flare/1.0.0/sample.mp4","sampleBytes":1386482}},"files":[{"path":"LICENSE","size":1072,"sha256":"8a5f3a96f07e11522ec4bdd0a583356f99bad1245920f9709cee09b995a45153","contentType":"text/plain; charset=utf-8","url":"https://aipixelwizard.com/registry/lens-flare/1.0.0/LICENSE"},{"path":"asset.json","size":9559,"sha256":"9e21fa8a7ec09bb27155ccdeff555e339d47249a0bc1960592aa6e92ae8b8f40","contentType":"application/json; charset=utf-8","url":"https://aipixelwizard.com/registry/lens-flare/1.0.0/asset.json"},{"path":"demo.js","size":3982,"sha256":"47e84015107f079874e82f4b4870d432b855f9764d6124edfc6c8b9016c933ab","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/lens-flare/1.0.0/demo.js"},{"path":"index.html","size":524,"sha256":"30e5ef85255ef0afcea9aed2b7d4867ae48a407827a2ebff01d7f2b5c039b269","contentType":"text/html; charset=utf-8","url":"https://aipixelwizard.com/registry/lens-flare/1.0.0/index.html"},{"path":"src/lens-flare.js","size":15230,"sha256":"9435a68b3c871340baa8a27aceb0755fbf46eb80984795cb164ff6a4364b0743","contentType":"text/javascript; charset=utf-8","url":"https://aipixelwizard.com/registry/lens-flare/1.0.0/src/lens-flare.js"}],"warnings":[]}