От автора: недавно я увидел весёлую анимацию, в которой использовались hover эффекты, на сайте Grover и просто был поражён нею. Когда вы наводите курсор на кнопку «Подписаться», там отображается цветной градиент, который следует за движениями курсора. Идея довольно простая, но в результате получается кнопка, которая отличается от остальных, и на которую просто невозможно не нажать.
Как же нам добиться похожего эффекта, который выделял бы наш сайт среди остальных? На самом деле, это намного легче, чем вам кажется!
Определение положения курсора
Первое, что нам нужно, это положение курсора.
1 2 3 4 5 6 7 |
document.querySelector('.button').onmousemove = (e) => { const x = e.pageX - e.target.offsetLeft const y = e.pageY - e.target.offsetTop e.target.style.setProperty('--x', `${ x }px`) e.target.style.setProperty('--y', `${ y }px`) } |
Выберите элемент и подождите, пока пользователь наведёт на него курсор
Вычислите положение относительно элемента
Сохраните координаты в переменных CSS
Именно так, всего 9 строчек кода проинформируют CSS о положении мышки пользователя. Благодаря этой информации вы уже можете добиться огромного количества эффектов. Но давайте сначала закончим CSS…
Анимируем градиент
Теперь координаты хранятся в переменных CSS и мы можем применить их в CSS где угодно.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
.button { position: relative; appearance: none; background: #f72359; padding: 1em 2em; border: none; color: white; font-size: 1.2em; cursor: pointer; outline: none; overflow: hidden; border-radius: 100px; span { position: relative; } &::before { --size: 0; content: ''; position: absolute; left: var(--x); top: var(--y); width: var(--size); height: var(--size); background: radial-gradient(circle closest-side, #4405f7, transparent); transform: translate(-50%, -50%); transition: width .2s ease, height .2s ease; } &:hover::before { --size: 400px; } } |
Оберните текст в span, чтобы избежать появления градиента выше него
Начните с width и height со значением 0px и увеличьте до 400px, когда пользователь наведёт курсор на кнопку. И не забывайте настроить переход так, чтобы он проносился со свистом
Используйте координаты, чтобы следить за мышкой
Примените radial-gradient к background и используйте closest-side circle. Closest-side заполнит весь before не выходя за его границы.
Результат
То, что надо! Добавьте отсутствующий HTML и наслаждайтесь кнопочкой:
Невероятные возможности
Вы можете создать очень много эффектов просто, благодаря отслеживанию положения мышки. С ними весело экспериментировать, к тому же, выглядят они блестяще. Ниже представлена похожая анимация, которую я использовал на веб-сайте basicScroll.
Или вы можете изощриться и создать кнопку с 3D параллаксом. Возможности безграничны.
Вопросы и ответы
Почему Вы анимируете width и height вместо того, чтобы использовать transform: scale()?
Производительность при анимации width и height плохая, старайтесь по возможности всегда использовать transform. Так почему же я не делаю того, что должен? Проблема в том, что браузеры отображают элементы (которые изменяются) в ускоренном слое. Этот слой может привести к проблемам, если у кнопки непрямоугольные края.
Исправление: Существуют способы использования transform, но некоторым браузерам они не нравятся. Потенциальное решение – это не применять transition к transform. Также есть обходные решения для Safari, которые могли бы исправить эти проблемы отсечения.
Проблема с ускоренными слоями и border-radius. Зачем изменять top и left вместо того, чтобы использовать transform: translate()?
Объяснение приведено выше.
Автор: Tobias Reich
Источник: //blog.prototypr.io/
Редакция: Команда webformyself.