Hairline crosshairs with edge rulers, a coordinate readout and drag-to-measure
| Name | Type | Default | Description |
|---|---|---|---|
color | string | "currentColor" | Ink of the crosshair, rulers, guides and pin notes, and the fill of the ink chip. The default inherits the surrounding text colour, so it follows light and dark themes. |
accentColor | string | "#7B5CFF" | Colour of the marker, the ruler notches, pins and the measuring line. Chip text picks black or white automatically for contrast. |
lineWidth | number | 1 | Hairline thickness in CSS pixels. Lines snap to whole device pixels so they stay sharp on every screen. |
lineStyle | "solid" | "dashed" | "dotted" | "solid" | Stroke of the crosshair. Dashes are anchored to the page, so they never crawl as the cursor moves. |
lineOpacity | number | 0.35 | Opacity of the crosshair, from 0 to 1. The measuring guides scale with it. |
gap | number | 9 | Clear radius in pixels around the exact point, where the lines stop. It tightens while a button is held. |
edgeFade | number | 0 | Fades the crosshair out towards the edges of the component, from 0 (none) to 1 (long fade). |
marker | "dot" | "ring" | "square" | "cross" | "none" | "dot" | Shape drawn at the exact point. Over links and buttons a thin ring opens around it. |
markerSize | number | 6 | Diameter of the marker in pixels. |
showCoordinates | boolean | true | Show the live coordinate readout beside the point. |
label | string | "" | Text shown at the start of the readout chip, for example "Aim". With coordinates off, the chip shows only the label. |
units | "px" | "percent" | "normalized" | "px" | Units of the readout, the pin notes and the ruler labels. |
origin | "top-left" | "center" | "bottom-left" | "top-left" | Where zero sits. Center and bottom-left count Y upwards, like a drawing; top-left counts down, like the screen. |
chip | "ink" | "accent" | "subtle" | "ink" | Fill of the readout chip: solid ink, the accent colour, or a faint raised tint of the ink. |
fontFamily | string | ui-monospace stack | Font of the readout, ruler labels and notes. A monospaced font keeps the readout from changing width. |
rulers | "hover" | "always" | "none" | "hover" | Edge rulers along the top and left. On hover they unfold with the crosshair; always keeps them on the page with a one-time sweep in. |
rulerSize | number | 20 | Depth of the rulers in pixels. |
tickSpacing | number | 10 | Pixels between minor ruler ticks in px units. Every fifth tick is longer and every tenth is labelled. |
grid | number | 0 | Grid pitch in pixels. Above zero, a small patch of grid crosses appears around the cursor and snapping uses this pitch. |
snap | boolean | false | Snap the point to the grid, or to the ruler ticks when there is no grid. The crosshair glides between detents. |
smoothing | number | 0 | Follow lag from 0 (exact, like a native cursor) to 1 (soft and floaty). |
measure | boolean | true | Press and drag to measure: a dimension line with its run, rise, angle and length. Hold Shift to lock to 45° steps, press Escape to cancel. Turn it off if visitors need to select text inside. |
measureHold | number | 2.5 | Seconds a finished measurement stays before it fades. Pass Infinity to keep it until the next one. |
pins | boolean | true | Click without dragging to stamp a pin with its coordinates. Clicks on links, buttons and fields never pin. |
maxPins | number | 4 | Pins kept at once. The oldest fades out when a new one lands. |
pinLife | number | 8 | Seconds a pin stays before it fades. 0 keeps pins until they are pushed out. |
intro | boolean | true | Unfold the crosshair from the point to the edges when it appears, and fold it back when it leaves. |
introDuration | number | 0.7 | Seconds the first unfold takes. Later entries run a little faster. |
autoplay | boolean | false | While the pointer is away, a ghost operator glides around, takes measurements and drops pins. It hands over to the real pointer the moment it enters. |
autoplaySpeed | number | 1 | Speed multiplier for the autoplay operator. |
idleDelay | number | 1.5 | Seconds after the pointer leaves before autoplay resumes. |
hideCursor | boolean | true | Hide the native cursor inside the component. Text fields keep their caret, and the crosshair steps aside over them. |
interactive | boolean | true | Follow the visitor's pointer. Turn it off to show only autoplay or scripted measurements. |
disabled | boolean | false | Hide the crosshair and ignore all input. |
formatCoordinates | (x: number, y: number) => string | undefined | Custom readout text. Receives the coordinates after units and origin are applied. |
onMeasure | (measurement) => void | undefined | Called when a measuring drag ends, with x1, y1, x2, y2, dx, dy, length and angle in pixels and degrees. |
onPin | (pin: { x, y }) => void | undefined | Called when a click drops a pin, with its position in pixels from the top-left corner. |
ref | { measure, pin, clearPins, replay } | — | Script it: measure(x1, y1, x2, y2) draws a measurement, pin(x, y) stamps a pin, clearPins() fades them all, replay() unfolds the crosshair again. |
data-cursor-label | attribute | — | Put it on any element inside to show that text in the chip while the pointer is over it. |
data-cursor="native" | attribute | — | Keep the native cursor over an element, the same way text fields do. |
children | ReactNode | — | Content the crosshair draws over. |
className | string | — | Classes for the root element. It fills its parent and is at least 240px tall. |
style | CSSProperties | — | Inline styles for the root element. |
colorstringInk of the crosshair, rulers, guides and pin notes, and the fill of the ink chip. The default inherits the surrounding text colour, so it follows light and dark themes.
"currentColor"accentColorstringColour of the marker, the ruler notches, pins and the measuring line. Chip text picks black or white automatically for contrast.
"#7B5CFF"lineWidthnumberHairline thickness in CSS pixels. Lines snap to whole device pixels so they stay sharp on every screen.
1lineStyle"solid" | "dashed" | "dotted"Stroke of the crosshair. Dashes are anchored to the page, so they never crawl as the cursor moves.
"solid"lineOpacitynumberOpacity of the crosshair, from 0 to 1. The measuring guides scale with it.
0.35gapnumberClear radius in pixels around the exact point, where the lines stop. It tightens while a button is held.
9edgeFadenumberFades the crosshair out towards the edges of the component, from 0 (none) to 1 (long fade).
0marker"dot" | "ring" | "square" | "cross" | "none"Shape drawn at the exact point. Over links and buttons a thin ring opens around it.
"dot"markerSizenumberDiameter of the marker in pixels.
6showCoordinatesbooleanShow the live coordinate readout beside the point.
truelabelstringText shown at the start of the readout chip, for example "Aim". With coordinates off, the chip shows only the label.
""units"px" | "percent" | "normalized"Units of the readout, the pin notes and the ruler labels.
"px"origin"top-left" | "center" | "bottom-left"Where zero sits. Center and bottom-left count Y upwards, like a drawing; top-left counts down, like the screen.
"top-left"chip"ink" | "accent" | "subtle"Fill of the readout chip: solid ink, the accent colour, or a faint raised tint of the ink.
"ink"fontFamilystringFont of the readout, ruler labels and notes. A monospaced font keeps the readout from changing width.
ui-monospace stackrulers"hover" | "always" | "none"Edge rulers along the top and left. On hover they unfold with the crosshair; always keeps them on the page with a one-time sweep in.
"hover"rulerSizenumberDepth of the rulers in pixels.
20tickSpacingnumberPixels between minor ruler ticks in px units. Every fifth tick is longer and every tenth is labelled.
10gridnumberGrid pitch in pixels. Above zero, a small patch of grid crosses appears around the cursor and snapping uses this pitch.
0snapbooleanSnap the point to the grid, or to the ruler ticks when there is no grid. The crosshair glides between detents.
falsesmoothingnumberFollow lag from 0 (exact, like a native cursor) to 1 (soft and floaty).
0measurebooleanPress and drag to measure: a dimension line with its run, rise, angle and length. Hold Shift to lock to 45° steps, press Escape to cancel. Turn it off if visitors need to select text inside.
truemeasureHoldnumberSeconds a finished measurement stays before it fades. Pass Infinity to keep it until the next one.
2.5pinsbooleanClick without dragging to stamp a pin with its coordinates. Clicks on links, buttons and fields never pin.
truemaxPinsnumberPins kept at once. The oldest fades out when a new one lands.
4pinLifenumberSeconds a pin stays before it fades. 0 keeps pins until they are pushed out.
8introbooleanUnfold the crosshair from the point to the edges when it appears, and fold it back when it leaves.
trueintroDurationnumberSeconds the first unfold takes. Later entries run a little faster.
0.7autoplaybooleanWhile the pointer is away, a ghost operator glides around, takes measurements and drops pins. It hands over to the real pointer the moment it enters.
falseautoplaySpeednumberSpeed multiplier for the autoplay operator.
1idleDelaynumberSeconds after the pointer leaves before autoplay resumes.
1.5hideCursorbooleanHide the native cursor inside the component. Text fields keep their caret, and the crosshair steps aside over them.
trueinteractivebooleanFollow the visitor's pointer. Turn it off to show only autoplay or scripted measurements.
truedisabledbooleanHide the crosshair and ignore all input.
falseformatCoordinates(x: number, y: number) => stringCustom readout text. Receives the coordinates after units and origin are applied.
undefinedonMeasure(measurement) => voidCalled when a measuring drag ends, with x1, y1, x2, y2, dx, dy, length and angle in pixels and degrees.
undefinedonPin(pin: { x, y }) => voidCalled when a click drops a pin, with its position in pixels from the top-left corner.
undefinedref{ measure, pin, clearPins, replay }Script it: measure(x1, y1, x2, y2) draws a measurement, pin(x, y) stamps a pin, clearPins() fades them all, replay() unfolds the crosshair again.
—data-cursor-labelattributePut it on any element inside to show that text in the chip while the pointer is over it.
—data-cursor="native"attributeKeep the native cursor over an element, the same way text fields do.
—childrenReactNodeContent the crosshair draws over.
—classNamestringClasses for the root element. It fills its parent and is at least 240px tall.
—styleCSSPropertiesInline styles for the root element.
—