Кастомные курсоры позволяют изменить стандартный указатель мыши на любой визуальный элемент, создавая уникальный пользовательский интерфейс. В JavaScript реализация кастомного курсора строится на отслеживании событий движения мыши и динамическом позиционировании DOM-элемента.
const cursor = document.createElement('div');
cursor.classList.add('custom-cursor');
document.body.appendChild(cursor);
document.addEventListener('mousemove', (e) => {
cursor.style.left = `${e.clientX}px`;
cursor.style.top = `${e.clientY}px`;
});
Ключевые моменты:
mousemove предоставляет координаты курсора.transform: translate(-50%, -50%),
чтобы центр элемента совпадал с курсором..custom-cursor {
width: 20px;
height: 20px;
border: 2px solid #000;
border-radius: 50%;
position: fixed;
pointer-events: none;
transform: translate(-50%, -50%);
transition: background 0.3s, transform 0.1s;
}
Прямое присваивание координат мыши делает движение курсора резким. Для создания плавного эффекта применяются методы интерполяции, такие как линейная интерполяция (lerp):
let mouseX = 0, mouseY = 0;
let cursorX = 0, cursorY = 0;
document.addEventListener('mousemove', (e) => {
mouseX = e.clientX;
mouseY = e.clientY;
});
function animate() {
cursorX += (mouseX - cursorX) * 0.1;
cursorY += (mouseY - cursorY) * 0.1;
cursor.style.transform = `translate(${cursorX}px, ${cursorY}px)`;
requestAnimationFrame(animate);
}
animate();
Принцип работы:
mouseX и mouseY — текущие координаты
мыши.cursorX и cursorY — текущие координаты
кастомного курсора.0.1 задает скорость следования курсора.Такое решение делает движение курсора плавным и естественным.
Кастомный курсор можно менять в зависимости от взаимодействия с элементами страницы:
const links = document.querySelectorAll('a');
links.forEach(link => {
link.addEventListener('mouseenter', () => cursor.classList.add('hover'));
link.addEventListener('mouseleave', () => cursor.classList.remove('hover'));
});
CSS для состояний:
.custom-cursor.hover {
transform: translate(-50%, -50%) scale(2);
background: rgba(0, 0, 0, 0.2);
}
Особенности:
mouseenter и mouseleave
позволяет динамически менять стиль курсора.scale увеличивает элемент курсора при
наведении на интерактивные элементы.transition.Smooth Scroll влияет на координаты элементов при прокрутке страницы. При использовании кастомного курсора необходимо учитывать смещение страницы:
let scrollY = 0;
window.addEventListener('scroll', () => {
scrollY = window.scrollY;
});
function animateCursor() {
cursorX += (mouseX - cursorX) * 0.1;
cursorY += (mouseY - cursorY + scrollY) * 0.1;
cursor.style.transform = `translate(${cursorX}px, ${cursorY}px)`;
requestAnimationFrame(animateCursor);
}
animateCursor();
Замечания:
position: fixed остаются корректными,
но для элементов с position: absolute требуется
корректировка на смещение.Для создания более выразительных кастомных курсоров применяются дополнительные техники:
let lastX = 0, lastY = 0;
function animateSpeed() {
const dx = mouseX - lastX;
const dy = mouseY - lastY;
const speed = Math.sqrt(dx*dx + dy*dy);
cursor.style.width = `${20 + speed / 5}px`;
cursor.style.height = `${20 + speed / 5}px`;
lastX = mouseX;
lastY = mouseY;
requestAnimationFrame(animateSpeed);
}
animateSpeed();
Кастомные курсоры активно используют
requestAnimationFrame, что позволяет синхронизировать
анимацию с перерисовкой браузера. Для высокой производительности
важно:
transform вместо
top/left.mousemove,
оставляя только обновление целевых координат.На сенсорных устройствах курсор не нужен, поэтому применяются условия:
if (!('ontouchstart' in window)) {
document.body.appendChild(cursor);
}
Это предотвращает лишние элементы и повышает производительность на планшетах и смартфонах.
Кастомные курсоры в сочетании с Smooth Scroll и динамическими эффектами позволяют создавать богатые визуальные интерфейсы, управляя вниманием пользователя и добавляя уникальность веб-странице.