Dot Cursor Follower
A small dot replaces the native cursor and tracks the pointer inside its panel.
3 frameworksBeginner
A dark panel that reveals its content through a radial spotlight following the pointer.
<!--
The overlay is a radial-gradient with a transparent hole at (--x,--y). Off
hover the vars default off-panel, so the whole panel reads dark; on move only
the CSS variables change. There is no transform equivalent for a moving mask -
updating two custom properties is the cheapest honest way to do it.
-->
<div id="cursor-spot-stage" class="relative w-full max-w-lg overflow-hidden rounded-2xl border border-gray-800 bg-gray-950">
<div class="flex h-56 flex-col items-center justify-center gap-2 px-6 text-center">
<h3 class="text-lg font-semibold text-white">Hidden in plain sight</h3>
<p class="max-w-xs text-sm text-gray-300">The panel stays dark until your pointer lights a path across it.</p>
</div>
<div id="cursor-spot" class="pointer-events-none absolute inset-0 transition-[background] duration-150 motion-reduce:transition-none"
style="background: radial-gradient(120px circle at var(--x, -1000px) var(--y, -1000px), transparent 0%, transparent 45%, rgba(2,6,23,0.94) 78%)"
aria-hidden="true"></div>
</div>
<script>
(() => {
const stage = document.getElementById('cursor-spot-stage');
const spot = document.getElementById('cursor-spot');
if (!stage || !spot || !matchMedia('(pointer: fine)').matches) return;
let rect = stage.getBoundingClientRect();
const set = (e) => {
spot.style.setProperty('--x', (e.clientX - rect.left) + 'px');
spot.style.setProperty('--y', (e.clientY - rect.top) + 'px');
};
stage.addEventListener('pointerenter', (e) => { rect = stage.getBoundingClientRect(); set(e); });
stage.addEventListener('pointermove', set);
stage.addEventListener('pointerleave', () => {
spot.style.setProperty('--x', '-1000px'); spot.style.setProperty('--y', '-1000px');
});
})();
</script>| Prop | Type | Default | Description |
|---|---|---|---|
heading | string | 'Hidden in plain sight' | Heading |
copy | string | 'The panel stays dark until your pointer lights a path across it.' | Body text shown under the title. |
radius | number | 120 | Radius |
className | string | - | Additional classes merged onto the root element. |
Set the reveal size with `radius`; the mask is a radial gradient positioned by two CSS variables, so only custom properties change on move. Off hover the hole parks off-panel and the surface reads fully dark.