Dot Cursor Follower
A small dot replaces the native cursor and tracks the pointer inside its panel.
3 个框架初级
Hovering a link floats a thumbnail preview that follows the pointer.
<!--
Hovering a link floats a thumbnail that follows the pointer. Visibility flips
on enter/leave (cheap); position is a transform written on pointermove. The
peek is aria-hidden - it is a visual flourish, and each link already names its
destination.
-->
<div id="cursor-peek-stage" class="relative w-full max-w-lg overflow-hidden rounded-2xl border border-gray-200 bg-gray-50 p-4 dark:border-gray-800 dark:bg-gray-900">
<ul class="divide-y divide-gray-200 dark:divide-gray-800">
<li><a href="#" data-grad="linear-gradient(135deg,#6366f1,#ec4899)" class="cursor-peek-link block rounded-md px-3 py-3 text-sm font-medium text-gray-800 hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:text-gray-100 dark:hover:bg-gray-800">Aurora Report 2026</a></li>
<li><a href="#" data-grad="linear-gradient(135deg,#06b6d4,#3b82f6)" class="cursor-peek-link block rounded-md px-3 py-3 text-sm font-medium text-gray-800 hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:text-gray-100 dark:hover:bg-gray-800">Field Notes</a></li>
<li><a href="#" data-grad="linear-gradient(135deg,#f59e0b,#ef4444)" class="cursor-peek-link block rounded-md px-3 py-3 text-sm font-medium text-gray-800 hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:text-gray-100 dark:hover:bg-gray-800">Case Study: Northwind</a></li>
<li><a href="#" data-grad="linear-gradient(135deg,#10b981,#14b8a6)" class="cursor-peek-link block rounded-md px-3 py-3 text-sm font-medium text-gray-800 hover:bg-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-600 dark:text-gray-100 dark:hover:bg-gray-800">Changelog</a></li>
</ul>
<div id="cursor-peek" class="pointer-events-none absolute left-0 top-0 opacity-0 transition-opacity duration-150" aria-hidden="true">
<div id="cursor-peek-img" class="h-24 w-32 -translate-x-1/2 -translate-y-1/2 overflow-hidden rounded-lg border border-white/20 shadow-lg"></div>
</div>
</div>
<script>
(() => {
const stage = document.getElementById('cursor-peek-stage');
const peek = document.getElementById('cursor-peek');
const img = document.getElementById('cursor-peek-img');
if (!stage || !peek || !img || !matchMedia('(pointer: fine)').matches) return;
let rect = stage.getBoundingClientRect();
stage.addEventListener('pointerenter', () => { rect = stage.getBoundingClientRect(); });
stage.addEventListener('pointermove', (e) => {
peek.style.transform = 'translate3d(' + (e.clientX - rect.left) + 'px,' + (e.clientY - rect.top) + 'px,0)';
});
stage.querySelectorAll('.cursor-peek-link').forEach((a) => {
a.addEventListener('pointerenter', () => { img.style.backgroundImage = a.dataset.grad; peek.style.opacity = '1'; });
a.addEventListener('pointerleave', () => { peek.style.opacity = '0'; });
});
})();
</script>| Prop | 类型 | 默认值 | 说明 |
|---|---|---|---|
items | PeekItem[] | (4 sample links) | 要渲染的项目数组。 |
className | string | - | 合并到根元素上的额外类名。 |
Pass `items` of `{ label, href, gradient }`; a CSS gradient stands in for a real thumbnail. The active item changes only on enter/leave while the peek position is a transform on move, and it is `aria-hidden` since each link already names its target.