Как заменить :hover на предиктивные анимации с onpointermove
С выходом новых инструментов и моделей (вроде Claude Opus 4.8) сообщество разработчиков окончательно перешло в эру Design Engineering. Грань между дизайном и кодом стёрлась, но многие продолжают использовать устаревшие подходы к микро-взаимодействиям. Один из главных «пережитков» — это бинарный ховер.
В этой статье разберём, как заменить дёрганый :hover на плавную, предиктивную анимацию, которая реагирует на курсор ещё до того, как он коснётся элемента. Результат — интерфейс, который чувствует пользователя.
Что не так с обычным :hover
Стандартный псевдокласс :hover работает по принципу «всё или ничего»:
- Курсор зашёл на элемент — стили применились мгновенно.
- Курсор вышел — стили сбросились.
Это бинарное поведение. Оно резкое, предсказуемое, но... бездушное. В современных интерфейсах пользователь ожидает плавности и отзывчивости, как в нативных приложениях macOS или iOS. Бинарный ховер не даёт ощущения «физичности» — элемент не тянется к курсору, не оживает, а просто переключается между двумя состояниями.
Почему это важно? Исследования UX показывают, что плавные микро-анимации снижают когнитивную нагрузку и повышают вовлечённость. Пользователь подсознательно чувствует, что интерфейс «живой», и доверяет ему больше.
Основная идея: реакция до наведения
Предиктивный интерфейс — это когда элементы начинают реагировать на курсор до того, как он окажется прямо над ними. Чем ближе курсор, тем сильнее эффект. Чем дальше — тем слабее. Никаких резких переключений.
Это напоминает поведение док-панели в macOS: иконки увеличиваются плавно, «подтягиваясь» к указателю. Эффект работает не только эстетически, но и функционально — пользователю проще целиться в мелкие элементы, потому что интерфейс сам помогает, увеличивая цель при приближении.
В вебе это реализуется через отслеживание положения курсора с помощью события onpointermove.
Механика работы на JavaScript
Давайте разберём код, который реализует этот эффект. Базовая идея проста:
- Ловим событие
pointermoveна всем документе (или на контейнере). - Для каждого элемента вычисляем расстояние от его центра до текущей позиции курсора.
- Чем меньше расстояние, тем больше коэффициент масштабирования.
- Затухание эффекта по мере удаления курсора за пределы зоны чувствительности.
Вот минимальный рабочий пример:
onpointermove = (e) => {
document.querySelectorAll(".dock > *").forEach((el) => {
const rect = el.getBoundingClientRect();
const distance = Math.abs(e.clientX - rect.x - rect.width / 2);
const t = Math.max(0, 1 - distance / 120);
el.style.scale = 1 + t * 0.5;
});
};
Построчный разбор
getBoundingClientRect()— получает координаты и размеры элемента относительно окна просмотра. Это нужно, чтобы вычислить центр элемента по оси X.Math.abs(...)— берёт абсолютное расстояние по горизонтали от курсора до центра элемента. Если курсор слева или справа — без разницы, важна только дистанция.- 1 -
distance / 120— нормализует значение в диапазон от 1 до 0. 120 пикселей — это радиус чувствительности. Если курсор дальше 120px, тоtстановится отрицательным, иMath.max(0, ...)обрезает его до нуля. scale = 1 + t * 0.5— итоговый масштаб. Максимальное увеличение — 1.5× (когда курсор точно над центром элемента).
Преимущества предиктивного подхода
1. Плавность и естественность Элементы не дёргаются, а «тянутся» к курсору. Это создаёт ощущение, что интерфейс дышит и подстраивается под пользователя, а не ждёт его команд.
2. Улучшенная юзабилити для мелких элементов Кнопки, иконки, ссылки — всё, что маленькое, становится удобнее. Пользователь видит, что элемент «откликается» ещё до клика, и ему проще попасть по цели. Эффект Фиттса в действии: чем крупнее цель, тем быстрее её достигает курсор.
3. Работа на тач-устройствах Событие pointermove поддерживается не только на десктопах, но и на мобильных устройствах с тач-экранами. Конечно, на таче эффект срабатывает при касании и движении пальцем, а не при наведении (на таче нет ховера в классическом смысле). Но для интерактивных панелей и тулбаров это отличное дополнение.
4. Эстетика уровня native-приложений Тот самый эффект, за который все любят док-панель macOS. Реализовать его на вебе — значит поднять визуальное качество сайта или приложения на голову выше конкурентов.
Оптимизация производительности
Когда вы вызываете getBoundingClientRect() в цикле на каждый чих pointermove, это может ударить по производительности, особенно если элементов много. Вот несколько советов:
Используйте requestAnimationFrame — не обновляйте стили на каждый вызов pointermove. Пусть цикл анимации работает в своём ритме (обычно 60 fps), а обработчик события просто сохраняет последние координаты.
let mouseX = 0;
onpointermove = (e) => {
mouseX = e.clientX;
};
function animate() {
document.querySelectorAll(".dock > *").forEach((el) => {
const rect = el.getBoundingClientRect();
const distance = Math.abs(mouseX - rect.x - rect.width / 2);
const t = Math.max(0, 1 - distance / 120);
el.style.scale = 1 + t * 0.5;
});
requestAnimationFrame(animate);
}
animate();
Кэшируйте размеры — если элементы не меняют размер и положение, можно вызывать getBoundingClientRect() один раз при загрузке или при ресайзе, а не на каждый кадр.
Используйте will-change — подскажите браузеру, что свойство scale будет меняться:
.dock > * {
will-change: scale;
}
Применение в реальных интерфейсах
Этот паттерн подходит не только для док-панелей. Вот ещё несколько сценариев:
- Меню и сайдбары — пункты увеличиваются при приближении курсора, помогая целиться.
- Галереи и сетки карточек — карточка «поднимается» или увеличивается, когда курсор рядом, а не только когда он прямо на ней.
- Слайдеры и карусели — предпросмотр следующего/предыдущего элемента с плавным скейлом.
- Инструменты для рисования — кисти, ластики и прочие инструменты меняют размер в зависимости от близости курсора.
Design Engineering — новая реальность
С выходом Claude Opus 4.8 и других ИИ-инструментов порог входа в программирование интерфейсов резко снизился. Теперь даже дизайнер без глубоких знаний JS может попросить нейросеть написать такой код. Это и есть Design Engineering — когда дизайнер мыслит не только визуальными макетами, но и поведением, анимацией, логикой взаимодействия.
Раньше на реализацию плавного предиктивного ховера уходили часы или дни. Сейчас — минуты с хорошей промпт-инженерией. Грань между «нарисовал» и «запрограммировал» окончательно стёрлась. И это прекрасно.
Заключение
Хватит использовать :hover как единственный способ взаимодействия с курсором. Это прошлый век. Плавные предиктивные анимации на onpointermove — простой способ добавить интерфейсу «ума» и сделать пользовательский опыт по-настоящему качественным.
Начните с малого: возьмите док-панель, меню или галерею — и добавьте тот самый эффект, за который все любят macOS. Код занимает 5–10 строк. Эффект — запоминается навсегда.
onpointermove = (e) => {
document.querySelectorAll(".interactive").forEach((el) => {
const r = el.getBoundingClientRect();
const t = Math.max(0, 1 - Math.abs(e.clientX - r.x - r.width / 2) / 120);
el.style.scale = 1 + t * 0.5;
});
};
Попробуйте сегодня и вы уже не сможете вернуться к старому.
Авторизуйтесь, чтобы оставить комментарий.
Нет комментариев.
Тут может быть ваша реклама
Пишите info@aisferaic.ru