Кнопки как в Material Design / Materialize
На днях задался вопросом — как сделать эффект у кнопок как в фреймворке Material Design / Materialize. На просторах интернета нашел решение, написанное на чистом JS. Разобрался, немного переписал и решил выложить к себе на сайт.
Оглавление
Фреймворк Materialize предоставляет неплохой эффект для кнопок. При нажатии на кнопку, в месте нажатия образуется некая волна. Если кликнуть на центр кнопки, волны расходятся быстрее, если кликать на край — немного медленнее.
Потребовалось реализовать нечто похожее, но само собой без подключение фреймворка. В интернете нашел несколько интересных решений, есть даже на чистом CSS. Но больше всего меня заинтересовал вариант написанный на чистом JavaScript, с применением небольшой CSS анимации. Разобрался в нем и решил разместить у себя на сайте.
JavaScript код
Для начала напишем небольшой JS код:
// Ищем все кнопки
const buttons = document.getElementsByClassName('btn');
for (let i = 0; i < buttons.length; i++) {
buttons[i].addEventListener('click', function (e) {
// При нажатии на кнопку, внутри создаем элемент span, который и будет волной
const wave = document.createElement('span'),
// Получаем размеры и координаты элемента в месте клика относительно viewport
waveOffset = this.getBoundingClientRect();
// Вычисляем координаты вычитанием координат элемента из координат документа
const waveY = e.pageY - waveOffset.top,
waveX = e.pageX - waveOffset.left;
// Полученные координаты записываем в стили тегу span
wave.style.top = waveY + 'px',
wave.style.left = waveX + 'px',
wave.style.background = this.getAttribute('data-button-background');
// Внутри кнопки по клику создаем span с координатами, которые формируются в зависимости от того, куда кликнем
this.appendChild(wave);
// Удаляем созданный тег span после 1.5 секунд
setTimeout(function () {
wave.parentNode.removeChild(wave);
}, 1500);
});
}
Как и всегда, я проставил много комментариев. Но если тезисно — данный код находит все кнопки по классу .btn
, далее при клике внутри кнопки создается элемент span
, который будет создавать тот самый эффект волн как в Material Design / Materialize фреймворке.
При клике на элемент, скрипт вычисляет его координаты, вычитает их из координат документа (не путать с координатами браузера) и полученные координаты заносит в инлайновые стили top и left. Некая динамическая генерация волн.
Прописываем CSS стили
Динамическое определение волн есть. Но их еще нужно анимировать. Напишем несколько стилей и анимацию с помощью кейфреймов:
.btn {
position: relative;
overflow: hidden;
z-index: 1;
}
.btn span {
position: absolute;
height: 12px;
width: 12px;
border-radius: 100%;
background: #FFFFFF;
animation: buttonWave 1.6s;
}
@keyframes buttonWave {
0% {
opacity: 0.2;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(40);
}
}
Анимацию волн можно регулировать в @keyframes buttonWave
.
В одном из решений в интернете подсмотрел возможность задавать цвет волн с помощью дата атрибута:
<button class="btn btn-default" data-button-background="#323479">Button 1</button>
<button class="btn btn-default" data-button-background="#cb2e77">Button 2</button>
<button class="btn btn-default">Button 3</button>
Прозрачность цвета волн регулируется в @keyframes buttonWave
, через параметр opacity
. Но этот дата-атрибут можно просто не заполнять, скрипт ругаться не будет.
Результат и исходники
Время запросов: 0,1833 s
Количество запросов: 28
Источник: cache