Технології CSS для ефекту від пульсації матеріалу

Довідник з різних методик ефекту пульсацій за допомогою CSS та JavaScript

Нещодавно мені довелося реалізувати ефект пульсацій від дизайну матеріалів у веб-додаток. І тоді я зрозумів, що не маю уявлення, як це було здійснено. Це призвело мене до шляху вивчення існуючих реалізацій і навіть придумати абсолютно нову техніку, яка може бути корисною для вас.

Що це за ефект пульсації?

Зачекайте, ви не знаєте ефекту пульсацій від Матеріального дизайну Google? Ви живете в печері скільки років?

Ефект пульсації використовується при натисканні кнопки. Це працює так само, як для миші та сенсорної взаємодії.

Позиція, яку ви натискаєте або натискаєте на кнопку, називається точкою дотику. Звідти пульсація надсилається рухаючись назовні, втрачаючи непрозорість у міру збільшення, поки не заповнює всю кнопку. Потім він повністю зникає.

Динаміка цього ефекту пульсації схожа на брижі, які ви отримуєте, коли торкаєтесь рідкої поверхні або коли ви опускаєте скелю в озеро.

Пульсації ви знайдете в Інтернеті

Провівши деякі дослідження, я міг знайти дві основні методи, які використовуються для реалізації ефекту пульсацій у веб-додатках.

Використання :: після псевдоелемента

Використовуючи цю техніку, псевдоелемент кнопки :: після стилю складається як напівпрозоре коло та анімований для росту та в’янення. Кнопка контейнера повинна мати переповнення: приховано, щоб коло ніколи не переповнювалося поза поверхнею кнопки, а також положення: відносно, щоб полегшити розташування кола в межах кнопки. Детальніше про цю техніку ви можете прочитати в цій статті Іонуша Кольчеріу.

Одна з чудових речей у цій техніці - це чисте рішення CSS для ефекту пульсацій. Однак ефект пульсації завжди починається від центру кнопки, а не від точки дотику. Це не найприродніші відгуки.

Це можна вдосконалити за допомогою JavaScript для зберігання точки дотику та використання його для позиціонування пульсації. Це саме те, що material.io зробив для свого компонента веб-пульсацій. Він використовує змінні CSS для зберігання точки дотику, а :: після псевдоелемента використовує ці змінні для позиціонування.

Використання дочірніх елементів

По суті, ця методика використовує ту саму стратегію, що і раніше. Але замість псевдоелемента він додає проміжний елемент всередині кнопки, який потім може бути розміщений через JavaScript. Ця методика описана в цій статті Джей Томпкінс.

Найпростіша реалізація створює проміжок для кожного натискання кнопки і використовує положення миші на події клацання для зміни положення проміжку. Анімація CSS робить проміжок зростати та згасати, поки не стане повністю прозорим. Ми можемо вибрати видалити проміжок з DOM, як тільки анімація закінчиться, або просто залишити її там під килимом - ніхто не дійсно помітить прозорий проліт, який висить навколо.

Я знайшов іншу варіацію цього, в якій дочірній елемент є svg замість span, а svg анімований через JavaScript. Ця варіація пояснюється Деннісом Габелем, але по суті вона, здається, однакова і, можливо, дозволяє використовувати складні SVG форми та ефекти.

Проблема з поданням даних

Обидві описані вище методи здаються чудовими. Але це відбувається, коли я намагався застосувати їх до вхідних елементів з type = submit:

Чому вони не працюють?

Вхідним елементом є замінений елемент. Якщо коротко, це означає, що ви можете зробити з цими елементами дуже мало стосовно DOM та CSS. Зокрема, вони не можуть мати дочірніх елементів, а також псевдоелементів. Тепер зрозуміло, чому ці методи не вдається.

Отже, якщо ви використовуєте Матеріал дизайну, краще триматися подалі від введення [type = submit] та дотримуватися елементів кнопки. Або просто продовжуйте читати.

Додавання брижі для подання входів

У веб-додатку, над яким я працював, у нас уже було багато кнопок для надсилання. Для того, щоб змінити їх на інший елемент, знадобиться багато роботи та високий ризик зламати таблиці стилів та логіку JavaScript. Тож мені довелося розібратися, як додати брижі до існуючих кнопок подання.

Використовуючи обгортковий контейнер

Я швидко зрозумів, що можу обернути кнопку подання всередині елемента вбудованого блоку та використовувати елемент вбудованого блоку як поверхню пульсацій. Ось коротка демонстрація:

Хоча мені це рішення подобається за його простоту, воно все ще вимагало від мене розмітки в занадто багато місця. І я знав, що це буде крихке рішення - нові розробники вступлять у проект і створюють кнопки подання, не завівши їх належним чином в пульсацію. Тож я продовжував шукати інші рішення, які не потребували зміни DOM.

Радіальні градієнти

Синтаксис радіально-градієнта дозволяє мені контролювати як центр, так і розмір градієнта. Звичайно, це також дозволяє мені контролювати колір градієнта, включаючи напівпрозорі кольори. І він ніколи не переповнює елемент, до якого він застосовується. Тож здається, що він вже робить усе, що мені потрібно!

Не так швидко ... є одне, чого не вистачає: властивість фонового зображення не анімаційна. Я не міг змусити градієнт зростати і згасати до прозорого за допомогою анімації CSS. Мені вдалося змусити його зрости, анімувавши властивість розміру фону, але це було все, що я міг зробити.

Я спробував ще декілька речей, наприклад, маючи затухаючий коло як анімоване зображення (використовуючи формат apng), і застосував його як фонове зображення. Але тоді я не міг контролювати, коли цикл зображення починався і закінчувався.

Нарешті, рішення з JavaScript

Що ви не можете зробити в CSS, ви можете зробити це в JavaScript. Провівши більше часу, ніж я хотів визнати, намагаючись домогтися цього ефекту, використовуючи анімацію CSS, я просто відмовився і вирішив написати анімацію на JavaScript.

Я почав з рішення про радіальний градієнт вище, і застосував window.requestAnimationFrame, щоб зробити текучу анімацію радіального градієнта, зростаючи і згасаючи. Ось моє остаточне рішення:

Висновок

Таким чином, можна мати ефект пульсації на кнопках подання, тільки не тільки з CSS.

Я не міг знайти цю техніку задокументованою ніде в Інтернеті, тому називаю її власною. Техніка пульсації Леонардо не вимагає змін до DOM і працює для будь-якого елемента, оскільки не покладається на псевдоелементи або дочірні елементи. Однак це не бездоганне рішення.

По-перше, є продуктивність. Анімація градієнта за допомогою JavaScript ви втрачаєте багато оптимізацій браузера. Але, оскільки єдине властивість, що змінюється, - це фонове зображення, я б підозрював, що браузерам не потрібно буде перезавантажуватись, а просто вимагатиме повторного застосування стилів та перефарбовування елемента. На практиці саме так і відбувається, а продуктивність справді хороша. Виняток із цього твердження - Firefox Mobile, який чомусь не йде в ногу з анімацією. (редагувати: анімація гладка в сучасних версіях Firefox Mobile)

По-друге, техніка використовує властивість фонового зображення кнопки. Якщо ваш дизайн вимагає, щоб ваші кнопки мали зображення, застосоване до його фону, ефект пульсацій це би перекрив це. Якщо вам справді потрібне це зображення у вашому дизайні, то JavaScript можна модифікувати, щоб намалювати радіальний градієнт поверх існуючого фонового зображення.

По-третє, схоже, це не працює в Internet Explorer. Однак я не бачу жодної причини, чому він не повинен працювати з IE10 і вище. Можливо, це тому, що IE використовує інший синтаксис для радіально-градієнта. Але, хто дбає про IE в наші дні? (редагувати: цей метод працює без проблем у Internet Explorer 11)