Morphiq

Components / Animations / Focus Peaking

Focus Peaking

Hover the photograph, rest a finger on it, or Tab to a link it sits in, and its in-focus edges light up, as on a camera monitor. Defocus is a low-pass filter, so sharpness can be measured as the size of the local brightness gradient: the Sobel operator on luma, |∇Y| = √(Gx² + Gy²), one displayed pixel per tap, thresholded and painted over a dimmed picture. It is honest about what it finds — a sharp edge lights whether or not it is the subject.

Usage

import FocusPeaking from '@/components/focus-peaking'

<FocusPeaking src={photo} alt="" threshold={0.22} />

Installation

npx shadcn@latest add https://morphiq.prathampatel.design/r/focus-peaking.json

Model

|∇Y| = √(Gx² + Gy²) > threshold

Sobel on Rec. 709 luma, one displayed pixel per tap

Props

PropertyTypeDefaultDescription
srcstring—Image URL. Cross-origin images need CORS for their pixels to be read.
altstring''Names the picture, as on an <img>. Empty marks it decorative, and hides it from assistive technology unless it has been given a tabIndex.
activeboolean—Leave undefined to peak while a pointer is over the picture, while a finger rests on it (a tap peaks for a moment), and while keyboard focus is on the link or button the picture sits in — or on the picture itself, given a tabIndex. true or false holds it on or off instead.
colorstring'#ff3b30'Peaking colour. Any CSS colour.
thresholdnumber0.22Sobel magnitude an edge must clear to light up, on 0..1 luma. Lower lights softer edges.
dimnumber0.35How far the picture dims while peaking, 0..1, so the edges carry.
reachnumber0Distance around the pointer that peaks, px. 0 peaks the whole image. With a reach a finger can carry the disc (a sideways drag is then the picture's, not the page's), and so can the arrow keys while the picture itself has keyboard focus, which it can once given a tabIndex.
fadenumber240Time for peaking to come on, ms; it goes off in 70% of that. 0 switches at once.
trailnumber30How far the reach disc trails a moving hand, ms. 0 pins it to the pointer.
fit'cover' | 'contain''cover'How the image fills the box.
focusXnumber0.5Horizontal alignment of the image within the box, 0..1.
focusYnumber0.5Vertical alignment of the image within the box, 0..1.
resolutionnumber2Device-pixel-ratio cap for the canvas.