REFERENCE
- Gallery page: https://magpui.com/en/i/glass-lens-over-textured-web-pages-cfb6db
- First frame (image): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/glass-lens-over-textured-web-pages-cfb6db/shot.jpg
- Clip (mp4): https://dnioievkvxejjbxgwvko.supabase.co/storage/v1/object/public/media/glass-lens-over-textured-web-pages-cfb6db/clip.mp4
- Original post: https://x.com/eledure/status/2117567527307870649 by @eledure
Before building, download the first frame and look at it. If ffmpeg is available, download the clip and extract frames (ffmpeg -i clip.mp4 -vf fps=2 frame-%02d.png), then study the motion frame by frame. Match what you see; the text below describes it, the frames are the truth.
ASSETS
This needs real artwork, not shapes drawn in code. Use the files the user gives you (ask where they are). If you have an image generation tool, generate them with these prompts; otherwise leave clearly marked placeholders.
- Paper grain texture: Seamless tileable texture of warm off-white uncoated paper with fine fibers and subtle grain, flat even lighting, no shadows, no objects, square 1:1
BUILD: A circular glass magnifier lens that follows the pointer (or glides along a scripted path in a demo) over textured editorial web pages. Inside the lens the page is shown about 1.8x larger, with the content bending near the rim like a real convex lens and a thin rainbow fringe at the edge. The pages under it look physical: warm off-white paper with fine grain, large type that looks printed or inked, headlines whose edges bleed and break, marker lettering in red and blue. It should feel tactile, slow and crafted, like moving a loupe across a printed page.
DESIGN SYSTEM: Page background off-white #EDEBE7 with a subtle paper grain (noise at 4-6% opacity, slight fiber pattern). Body text dark gray #2B2B2B. Example page styles to support: (1) an editorial essay with a large grotesk headline 64-72px/1.05 and a serif body 15px/1.5; (2) a photo grid of grayscale images 4 columns, 16px gutters, small serif captions 11px; (3) a numbered index list with thin rules #BDB8B0, condensed bold headlines in deep red #7A1F24 with a rough, eroded edge; (4) a large heavy display line in near-black with an ink bleed; (5) a poster layout with condensed headline words in crimson #B1162B and cobalt #2B57C9 drawn like felt-tip marker strokes. Lens: diameter 240px desktop (180px mobile), perfectly round, no visible border, a soft inner highlight at the top-left (white gradient 0 to 18% opacity), a faint outer shadow 0 10px 30px rgba(0,0,0,0.12), and a 2-4px chromatic fringe at the rim (red outward, blue inward).
MOTION: Pointer follow: the lens center eases toward the pointer with a spring (stiffness 120, damping 20) or a lerp of 0.12 per frame, so it trails slightly. Magnification 1.8x at the center, falling off with a barrel distortion so the outer 15% of the radius compresses the content. On pointer enter of the page, the lens scales from 0.6 to 1 and fades in over 300ms, cubic-bezier(0.22, 1, 0.36, 1); on leave it shrinks and fades out over 220ms, cubic-bezier(0.4, 0, 1, 1). Demo mode: when idle for 3s, the lens glides along a slow S-shaped path across the page, about 8s per loop, ease-in-out. Optional: the ink headlines slowly breathe their edge roughness (noise offset drift over 6s) so the print feels alive.
SECTIONS: Parts: page layer (the real DOM content), texture layer (paper grain and ink displacement), lens layer. States: idle (no lens, or lens in demo path), hover (lens follows pointer), over text (magnified type stays crisp), over images (magnified photos, slight extra contrast), leave (lens shrinks out).
IMPLEMENTATION: Render the page normally in the DOM. For the lens, the most robust route is WebGL: capture the page section to a texture (html-to-canvas once per section, or design the demo pages directly in canvas) and draw a full-screen quad with a fragment shader that, inside the lens radius, samples the texture at uv = center + (uv - center) / zoom with a barrel term k * r^2, plus per-channel offsets at the rim for the chromatic fringe. A lighter alternative without WebGL: a cloned copy of the section inside a circular clip-path container, scaled 1.8x with transform-origin at the pointer, and an SVG feDisplacementMap with a radial map for the rim bend. Paper grain and ink bleed: an SVG feTurbulence + feDisplacementMap filter on headlines (scale 2-4) and a tiled noise PNG or shader noise over the background. Hide the lens on touch devices or make it draggable. prefers-reduced-motion: no trailing, no demo path, no breathing edges; the lens appears only on pointer and moves 1:1. The lens is decorative: aria-hidden, no focus trap; keep the real text selectable and readable. Performance: cap device pixel ratio at 2, rerender the texture only on resize or content change, keep the shader to one pass.
ADAPT TO THE PROJECT: Reuse the project's existing design tokens, fonts and components; map the colors to the closest existing tokens. Never copy logos, brand names, photos or illustrations from the original; use placeholder copy and placeholder grayscale images.
SUCCESS CHECK:
- Moving the pointer over the page shows a round lens that trails smoothly and magnifies the content under it about 1.8x, with visible bending and a thin color fringe at the rim.
- Headlines and background read as printed paper and ink (grain, rough edges), not flat vector.
- With reduced motion on, the lens follows 1:1 with no idle animation, and the page text stays selectable.