magic-cursor
Курсор·Шаблон: Liko - Creative Agency & Portfolio Next.js Template·Складність анімації: heavy·Адаптивний: Ні
Файли-джерела
- out/index.html
div#magic-cursor
Бібліотеки
gsapjquery
Summary
Custom dual-element cursor — a small dot (#magic-cursor) and a larger lerping ball (#ball) — that grow over interactive elements, swap to a "View Demo" label over portfolio thumbs, and hide the native pointer. Activated by adding the tp-magic-cursor class to body.
HTML structure (minimal)
<body class="tp-magic-cursor">
<div id="magic-cursor">
<div id="ball"></div>
</div>
<!-- Interactive elements opt-in via data-cursor attribute -->
<div class="tp-project-img not-hide-cursor" data-cursor="View<br>Demo">
<a class="cursor-hide" href="…"><img src="…" alt=""></a>
</div>
</body>
Key SCSS tokens
body.tp-magic-cursor, body.tp-magic-cursor * { cursor: none !important; }
#magic-cursor {
position: fixed; left: 0; top: 0;
pointer-events: none; z-index: 9999;
width: 12px; height: 12px;
border-radius: 50%;
background: var(--tp-common-black);
}
#ball {
position: fixed; left: 0; top: 0;
pointer-events: none;
width: 60px; height: 60px;
border-radius: 50%;
border: 1px solid var(--tp-common-black);
transition: width .3s, height .3s, background .3s, color .3s;
}
#ball.with-text { width: 120px; height: 120px; background: var(--tp-common-black); color: var(--tp-common-white); display: flex; align-items: center; justify-content: center; text-align: center; }
Animation logic
// src/plugins/tp-cursor.js — invoked from home-1.tsx via cursorAnimation()
// on mount. Listens to mousemove globally, lerps #magic-cursor exactly to
// the pointer and #ball with damping (smooth follow). On mouseenter of any
// [data-cursor] element it adds .with-text and sets innerHTML to that value.
// On mouseleave it resets.
useEffect(() => {
document.body.classList.add('tp-magic-cursor');
cursorAnimation();
return () => document.body.classList.remove('tp-magic-cursor');
}, []);
Notable details
- Two-layer cursor (sharp dot + soft follower) reads as both a precise pointer and a magnetic ball, which is rare in template land.
- Opt-in via
data-cursor="View<br>Demo"means content authors can change the label without editing JS. cursor-hideclass on inner<a>andnot-hide-cursoron outer container give per-element control over whether the native cursor shows under the magic one.
Use when
- Portfolio sites and case-study pages where the cursor itself becomes a UI signal.
- When you want hovered tiles to communicate intent ("View Demo", "Drag", "Play") without overlay HTML.
Caveats
- Disabled on touch devices — falls back to the native pointer; do test that interactive elements are still discoverable.
cursor: none !importantcascades to every child — accessibility audit may flag it; provide a toggle if necessary.