10 принципів створення плавної веб-анімації
Ми не хочемо вселити людям відчуття залежності від якогось неймовірного плагіна JavaScript, здатного чарівним чином створювати яскраві анімації. Секрет успіху набагато простіший.
10 принципів створення плавної веб-анімації
Немає ніякої «фішки» у створенні масштабної анімації. Хоча ні, є: треба витратити чимало часу на її оптимізацію та тестування. Так після кількох років експериментів, постійно упираючись у межі продуктивності браузерів, ми вивели серію принципів дизайну та кодингу, які дозволять будь-якому бажаючому прикрасити свій проект ефектною та продуктивною анімацією. Їх використання дозволить вам отримати плавну роботу сторінок у десктопних та мобільних браузерах. І найголовніше – все це робиться та обслуговується дуже просто.
Технологія та реалізація будуть трохи відрізнятися для кожного конкретного випадку, але ми впевнені, що наші загальні принципи виявляться корисними практично у будь-якій ситуації.
Що таке анімація?
Анімації існували ще до Інтернету. Для створення найкращих із них можна витратити все життя на навчання. Тим не менш, у цій справі також існують закономірності. Ми обговоримо деякі типові та не дуже проблеми, з якими стикаються дизайнери під час створення анімації для розміщення у вебі.
Для отримання плавної анімації з 60 fps кожен кадр повинен оброблятись менш ніж за 16 мс! Це малий проміжок часу, тому необхідно знайти дуже ефективні способи рендеринг кожного кадру для високої продуктивності анімації.
Існує безліч способів реалізації веб-анімації. Наприклад, кінострічка існувала ще до Інтернету.Суть її в тому, що вручну промальовані кадри з мінімальною відмінністю демонструвалися кілька разів на секунду, створюючи таким чином ілюзію руху у глядача.
Twitter нещодавно використовували цей простий підхід для їх нової анімації серця, прокручуючи у заданій послідовності 26 кадрів.
Отримана в такий спосіб анімація надто складна у реалізації і, насправді, недостатньо плавна.
У багатьох випадках вигідніше використовувати властивість CSS transition для автоматичної анімації елемента при його зміні. Ця техніка відома також як "tweening" і передбачає створення анімації з автоматичною побудовою проміжних зображень. Припустимо, ми маємо 2 зображення одного об'єкта у різних положеннях. Ефекти переходу CSS допоможуть створити анімацію зміни стану. Їх використання вигідно тим, що можна будь-якої миті скинути або звернути всю логіку анімації. Це ідеальний підхід із розряду «встановив і забув». Добре працює, наприклад, з різними інтро-послідовностями або простими взаємодіями на кшталт активації анімації при наведенні миші.
Також анімація, побудована в CSS на ключових кадрах, може бути ідеальним тлом для вибраних областей сторінки. Наприклад, кільця з логотипу "Гіроскопа" постійно обертаються. Такий підхід добре використовуватиме анімації руху різних механізмів.
Отже, із вступною закруглюємося і переходимо до основної частини посту. Дамо кілька порад, які допоможуть значно підвищити продуктивність та якість вашої анімації. Сподіваємось, вони вам допоможуть.
Не змінюйте жодних властивостей крім непрозорості (opacity) та перетворення (transform)
Навіть якщо вам здається, що так буде краще, не варто цього робити!
Дотримання цього базового принципу підвищить ефективність роботи на 80%, навіть у мобільному сегменті. Напевно, ви вже чули про це раніше. Ідея не оригінальна, але їй рідко йдуть. Вона є веб-еквівалентом «їжте здорову їжу та виконуйте фізичні вправи». Всі чули, знають, що це правильно, але мало хто дотримується.
Насправді до використання цього принципу досить просто звикнути. Особливу вигоду це принесе тим, хто робив анімації за допомогою традиційних властивостей CSS.
Наприклад, якщо вам потрібно зробити об'єкт меншим, ви можете використовувати властивість трансформації scale замість зміни ширини/висоти. Якщо вам потрібно перемістити елемент, то не варто вовтузитися зі зміною значень відступів, адже така анімація вимагатиме перебудови макета сторінки при кожному кадрі. Найкраще використовуйте прості властивості трансформацій для цього: transform:
translateX або transform:
translateY.
Чому це працює?
Для людини, що змінює ширину, відступи та інші подібні параметри використання властивостей трансформації може не виглядати видатною ідеєю. Візуально результат адже схожий. Але з точки зору витрат обчислювальної потужності комп'ютера, який все це обраховуватиме, використання transform виглядає в рази краще.
Розробники браузерів виконали величезну роботу для оптимізації таких операцій. Трансформації справді ефективні, вони заощаджують ресурси відеокарт, відкидаючи необхідність повторного рендерингу елемента.
Можна збожеволіти, очікуючи завантаження такої сторінки: всі кути заокруглені, використовуються зображення, на всі покладені тіні і для повного щастя додано динамічне розмиття елементів. Якщо таке відбувається 1 раз, то кілька зайвих мілісекунд очікування на роль не зіграють.Але коли весь контент буде виведений на екран, ви більше не захочете чекати перерахунку будь-яких значень для зміни сторінки.
Приховуйте контент на увазі
Використовуйте "pointer-events" у CSS: значення "none" поряд з нульовою непрозорістю для приховування елементів
Даний метод погано працює в старих браузерах, але якщо ви проектуєте для webkit або інших сучасних браузерних движків, він зробить ваше життя набагато простіше.
У далекі часи, коли анімації оброблялися за допомогою jQuery animate(), основна складність при роботі з ефектом fade полягала в необхідності перемикання значення якості display: активувати none для припинення ефекту в потрібний момент. Занадто рано і анімація не буде завершена, надто пізно і ви отримуєте невидимий елемент з нульовим значенням opacity, що перекриває сторінку. Потрібен зворотний відгук для очищення екрана після завершення анімації.
Властивість CSS «pointer-events» (існує давно, але чомусь використовують його нечасто) служить для того, щоб зробити речі нечутливими до кліків мишею та іншими взаємодіями. Так, ніби їх взагалі нема на сторінці. Ця властивість може бути легко увімкнена/вимкнена за допомогою CSS. Під час роботи воно не перериває анімацію та не впливає на рендеринг/видимість елементів.
Комбінуючи цю річ з нульовим значенням opacity, ми отримуємо той самий ефект, що дає display: none, але без впливу на продуктивність при запуску нових циклів рендерингу анімації. Якщо потрібно приховати елемент із поля зору, я зазвичай виставляю нульову непрозорість і вимикаю pointer-events. Після цього можу забути про нього, знаючи, що все легко повернути назад і нічого не заважатиме продуктивності сторінки.
Цей прийом особливо добре працює з елементами, що мають абсолютне позиціонування, оскільки в такому випадку ви можете бути впевнені в тому, що вони не впливають на всі інші ділянки макета та елементи сторінки.
Також це дає вам набагато більшу свободу дій, оскільки вибір часу початку/припинення анімації в такому разі може бути не дуже точним. Навіть якщо ви трохи помилитеся з таймінгами, нічого страшного не станеться. Користувач просто не зможе нічого натиснути до завершення анімації. Все йтиме так, як ви задумали.
Не потрібно анімувати все поспіль одночасно
Або використовуйте принцип хореографії.
Одна анімація може бути плавною сама по собі, але якщо одночасно відпрацьовується кілька ефектів, це може зіпсувати всю картину і знизити продуктивність. Створити демку, що плавно працює, дуже просто, зате забезпечити прийнятний рівень продуктивності у складі цілого сайту набагато складніше. Тому дуже важливо планувати появу анімації належним чином.
Ви захочете побудувати таймінги таким чином, щоб усі анімації запускалися у різний час. Зазвичай, 2-3 анімації можуть працювати без затримок одночасно, особливо якщо вони стартують з невеликим розкидом за часом. Більше 3 одночасних (на око, але не по суті – мінімальний розкид за часом має бути) запусків майже напевно викличуть лаги на екрані.
Якщо на сторінці більше однієї анімації вам важливо зрозуміти концепцію хореографії. Здавалося б, до чого тут танцювальний термін? Але розуміння його суті в даному контексті дуже важливе для успішної анімації інтерфейсів: речі повинні приходити на екран із правильного напрямку та у потрібні моменти.Незважаючи на те, що всі вони працюють окремо, для глядача вони мають виглядати як частини одного добре спроектованого механізму.
Матеріал-дизайн від Google має деякі цікаві напрацювання з цього питання. Це, звичайно, не єдино правильний шлях, але він дає їжу для роздумів та тестування.
Невелике збільшення затримки переходу дозволяє легко дотримуватися принципу хореографії
Хореографія анімації дуже важлива, і її якісна постановка вимагатиме великої кількості експериментів. Проте код для реалізації задуму навряд чи вийде дуже складним.
Я зазвичай замінюю один клас на батьківському елементі (найчастіше на body) для того, щоб викликати купу переходів, кожен із яких має свій параметр затримки (transition-delay). Робиться це для того, щоб кожен елемент з'являвся в потрібний час. З точки зору кодингу вам варто турбуватися про значення лише однієї змінної замість підтримки десятків таймінгів у JavaScript.
Розгойдуючи одночасно серію елементів, можна досить просто скомпонувати їхню хореографію. Це потужний підхід, тому що все це одночасно і виглядає добре, і працює швидко, лише пам'ятайте, що тільки 2-3 анімації можна запускати одночасно і все буде добре. Потрібно розповсюдити їх на сторінці так, щоб кожна відпрацьовувалася плавно та вчасно. Сет ваших анімацій має сприйматися глядачем як безперервний потік, а не ланцюжок розрізнених елементів. Єдина плавна сцена.
Приклад коду
Є кілька простих методів, які дозволять розгойдувати ваші елементи. Вони дуже зручні, особливо якщо ви використовуєте довгий ланцюжок анімацій. Якщо ланцюжок включає менше 10 елементів, я зазвичай вказую значення затримок в CSS. Це найпростіший спосіб реалізації.
Для більш довгих послідовностей або елементів таймінги, що дуже динамічно змінюються, можуть встановлюватися динамічно для всіх елементів шляхом зміни значень змінних.
Як правило, використовуються 2 змінні: ваша базова затримка та затримка за часом між кожним елементом. Такий баланс знайти досить складно, але якщо ви потрапите на правильний набір чисел, то все буде добре.
Використовуйте спільний множник для розробки у slow motion
І прискоріть все це згодом.
У дизайні анімації таймінг є нашим усім. 20% роботи криється у створенні самих анімацій, а решта 80% - у знаходженні правильних параметрів та таймінгів для отримання чітко синхронізованої та плавної сцени.
Особливо це актуально при роботі над хореографією безлічі елементів і спробах вичавити максимум продуктивності. Після уповільнення анімацій з такими сценами працюватиме набагато простіше.
Якщо ви використовуєте Javascript або якийсь CSS-препроцесор на кшталт SASS, код має бути досить простим для побудови правильної структури змінних.
Ви повинні переконатися у зручності кодової конструкції, щоб без проблем тестувати різні швидкості та таймінги. Наприклад, якщо анімація заїкається навіть на 1/10 швидкості, ви, швидше за все, робите щось докорінно неправильно. Якщо вона йде гладко при розтягуванні в 50 разів, то питання зводиться до знаходження максимальної швидкості, коли вона зможе плавно працювати. Досить важко помітити проблеми на повній швидкості, але якщо ви знизите її, всі вони стануть дуже очевидними.
Для налаштування дуже складних анімацій або при пошуку вузьких місць у продуктивності відстеження процесу в уповільненому темпі буде дуже корисним.
Ідея полягає в тому, щоб запакувати багато красивих деталей у сцену при уповільненій демонстрації, після чого прискорити всю цю справу так, щоб анімації виглядали ідеально. Це дуже тонка робота, зате користувачі оцінять деталізацію та плавність того, що відбувається на екрані.
Ця фішка є чинною частиною OS X: коли ви згортаєте вікно з програмою, бачите анімацію в уповільненому темпі.
Візьміть відео із записом вашого інтерфейсу та прокрутіть, від третьої особи ви зможете побачити більше
Іноді погляд з боку допомагає бачити речі більш ясно, і відео є чудовим способом досягти цього.
Деякі люди створюють відео в After Effects, після чого намагаються реалізувати отримане на сайті. Я часто роблю з точністю до навпаки, намагаючись зробити хороше відео на основі користувальницького інтерфейсу сайту.
Якось я був настільки вражений отриманим від роботи результатом, що вирішив поділитися з друзями відео з його записом. Проте, при повторному перегляді мною було помічено купу речей, далеких від захоплення. Були лаги та й таймінги виставлені трохи невірно. Це мене збентежило, і замість того, щоб розіслати відео, я взявся доводити результат до розуму. Роботи там залишалося чимало.
У режимі реального часу досить просто можна проґавити якісь моменти. Зате перегляд анімації в записі на повільній швидкості знову і знову допоможе виявити найменші проблеми. За такого підходу все стає очевидним.
Перегляд уповільнених відео з моїх сторінок та коригування проблемних ділянок стали важливою частиною моєї роботи. Можна, звичайно, все списувати на повільні браузери, але найчастіше після тестування та проведення оптимізації анімації починають працювати як по маслу. Тобто все вирішується за грамотного підходу.
Якщо після переглядів та правок мене нічого не бентежить, і я можу зі спокійною совістю поділитися таким відео з колегами та друзями, отже, проект готовий до релізу.
Активність Мережі може призвести до лагів
Вам потрібно попередньо завантажити або блокувати великі
HTTP-запити
Зображення виступають у цьому плані вирішальним фактором, особливо якщо вони великі за вагою (наприклад, важке тло), або тонна маленьких (завантаження 50-100 аватарів, допустимо), або просто велика кількість контенту (довга сторінка з купою картинок).
Під час першого завантаження сторінки тонни речей ініціалізуються та завантажуються. Оголошення, модулі та інші сценарії 3 черги завантаження ще більше посилюють ситуацію. Іноді затримка відтворення анімацій лише на кілька сотень мілісекунд після завантаження інших елементів сторінки здатна зробити диво. Ви отримаєте значний приріст продуктивності.
Не варто задіяти мега-оптимізацію без явної необхідності, хоча важка сторінка може вимагати встановлення дуже точних затримок та таймінгів анімації для плавної роботи. Загалом, потрібно для початку завантажити настільки малу кількість даних, наскільки це можливо, потім підключити анімацію, а вже після неї продовжити завантаження решти важкого контенту сторінки.
На сторінках з великою кількістю даних робота з оптимізації може тривати багато часу. Анімація, що працює добре зі статичним контентом, може почати гальмувати і розвалюватися при одночасному завантаженні з реальними даними. Якщо щось виглядає цілком плавно працюючим, але в деякі моменти починає класти з неясної причини, слід перевірити мережеву активність. Можливо, у цей момент ваш канал зайнятий іншими завантаженнями. Переконайтеся, що мережа не виконує кілька одночасних великих завантажень.
Не потрібно міняти стандартне прокручування
Ідея заміни скролла може здатися класною, але це не так насправді.
Скролінг на основі анімації популярний вже кілька років, особливо якщо він зроблений із застосуванням паралаксу та інших спецефектів. Про його корисність можна сперечатися довго, а ось способи технічної реалізації такого задуму є вдалими і не дуже.
Помірно ефективним способом створення речей із цієї категорії є визначення оптимального кроку прокручування та виділення його в окрему подію (event). Якщо ж ви не знаєте, що робите, краще взагалі не використовувати такий скролінг. Тут легко помилитися та й підтримувати нормальний рівень продуктивності на сторінках зі складним скролінгом – досить клопітне заняття.
Ще гіршою витівкою виглядає заміна стандартного скролла на так званий scrolljacking (контент змінюється в такт прокручування, приклад – сайт Apple). Не робіть цього. Реалізувати вдало такий ефект складно, та й не всім користувачам сподобається.
Якщо ви маєте певний досвід і бажання створити свій скроллбар, зробіть його полегшений прототип і протестуйте на працездатність, перш ніж витрачати час на повну розробку.
Найчастіше тестуйте свої проекти на мобільних пристроях
Більшість веб-сайтів створено на ПК. Найчастіше вони тестуються на тій же машині, де їх розробили. Таким чином, мобільна версія сайту та продуктивність анімацій відходять на задній план. Деякі технології створення анімації (наприклад, canvas) не будуть нормально працювати на мобільних платформах.
Тим не менш, якщо анімація буде зроблена та оптимізована належним чином, то отриманий від неї мобільний досвід використання може перевершувати за якістю десктопний. Мобільна оптимізація раніше була дуже складною темою, але нові iPhone працюють швидше за більшість ноутбуків.Якщо ви станете дотримуватися наведених вище порад, то зможете досягти значної продуктивності ваших анімацій і на мобільних пристроях.
Мобільна версія сайту – велика та дуже важлива його частина. Це може бути дивним, але я рекомендую протягом тижня переглядати ваш сайт виключно з телефону або планшета. В ідеалі ви не повинні відчувати, що отримали покарання через неможливість дістатися до робочого столу. Якщо все працює швидко, плавно і без порушень задуманої структури, ви досягли мети. Якщо щось йде не так, треба продовжувати роботу.
Продовжуйте вносити конструктивні вдосконалення та покращувати продуктивність, поки різниця у комфортності використання мобільної та десктопної версії сайту не зникне зовсім.
Якщо ви змусите себе використовувати мобільний сайт протягом тижня, то, ймовірно, зрештою, оптимізуєте його навіть краще, ніж більшу версію. Борючись із роздратуванням, використовуючи його на регулярній основі, ви повною мірою відчуєте проблеми, з якими доведеться зіткнутися вашим користувачам, і зможете усунути їх до виходу проекту в широкі маси. Це позбавить безліч проблем у майбутньому.
Тестуйте проекти на різноманітних пристроях
Існує безліч факторів, здатних кардинально вплинути на продуктивність сайту на ПК та мобільних пристроях: роздільна здатність екрану, кількість пікселів у вікні, старість заліза і т.д.
Незважаючи на те, що Chrome та Safari створені на базі Webkit і мають практично однаковий синтаксис, у кожного з них свої власні чудасії. Будь-яке оновлення Хрому одночасно усуває старі помилки і привносить нові, тому ви повинні постійно тримати руку на пульсі, як кажуть.
Зрозуміло, не всі хочуть йти шляхом найменшого опору, роблячи сайти по нижньому спільному знаменнику суми багів, щоб не потрапити в черговий просак після оновлень найпопулярніших браузерів.Пошук грамотних шляхів додавання удосконалень та видалення деяких із них для підтримки плавної роботи сайту може бути дуже корисним.
Я регулярно перемикаюся в роботі між моїм маленьким MacBook Air та великим iMac. Кожен такий цикл виявляє невеликі проблеми та вказує на необхідні удосконалення. Це стосується не тільки продуктивності роботи анімації, а й дизайну сайту в цілому, щільності інформації, читання, структури і т.д.
Моделі мобільної та звичайної версії сайту найчастіше відрізняються дизайном структури за шириною, висотою, щільністю пікселів та іншими властивостями. Знання особливостей операційних систем та апаратних характеристик мобільних пристроїв може допомогти в оптимізації, оскільки вони дуже відрізняються від таких на ПК.
Using the Web Animations API
Web Animations API дозволяє нам створити анімацію та керувати її відтворенням за допомогою JavaScript. Ця стаття буде правильним керівництвом для старту з веселими демками та уроками з Алісою у Країні Чудес.
Зустрічайте Web Animations API
Web Animations API відкриває анімацію на движку браузерів для розробників і маніпуляції через (за допомогою) JavaScript. Цей API був розроблений в основі реалізації CSS Animations та CSS Transitions і залишав свободу рухів для майбутніх анімаційних ефектів. Це один з найефективніших способів анімації, що підтримується в Інтернеті, дозволяючи браузеру зробити свою власну внутрішню оптимізацію без хаків, примусу або Window.requestAnimationFrame() .
З Web Animations API, ми можемо керувати інтерактивною анімацією зі стилями JavaScript, відокремлюючи уявлення від дії. Нам більше не потрібно покладатися на DOM-heavy методики написання CSS-властивостей та оглядових класів для елементів контролю відтворення напряму. І на відміну від суто декларативного CSS, JavaScript також дозволяє встановлювати динамічні значення властивостей та їх тривалість.Для створення бібліотек користувача та інтерактивної анімації Web Animations API може стати чудовим інструментом у роботі. Погляньмо, що він може зробити!
Написання CSS Animations разом із Web Animations API
Найпростіший спосіб навчання Web Animations API це почати з чого починала більшість веб-розробників: CSS Animations. CSS Animations має знайомий синтаксис, який добре розкриває структури демонстраційних прикладів.
CSS версія
Ось така анімація написана в CSS, що показує, як Аліса падає в кролячу нору, яка веде в країну чудес (див. повний код на Codepen):
Зверніть увагу, що фон рухається, Аліса крутиться і її колір змінюється при обертанні. Ми збираємося зосередитися тільки на Алісі у цьому уроці. Ось спрощений код CSS, який керує рухом Аліси.
#alice < animation: aliceTumbling infinite 3s linear; >@keyframes aliceTumbling < 0% < color: #000; transform: rotate(0) translate3D(-50%, -50%, 0); >30% < color: #431236; >100% < color: #000; transform: rotate(360deg) translate3D(-50%, -50%, 0); >>
Зміна кольору Аліси та її обертання протягом 3 секунд при постійній (лінійній) швидкості та нескінченному циклі. У @keyframes блоці бачимо, що 30% з усього циклу (близько 9 секунд), колір Аліси змінюється від чорного до насиченого бордового, а потім знову в чорний до кінця циклу.
Рух у JavaScript
Тепер давайте спробуємо створити таку саму анімацію з Web Animations API.
Представляючи кадри
Насамперед ми повинні створити Keyframe Object відповідного нашому CSS @keyframes блоку:
Тут ми використовуємо масив, який містить кілька об'єктів. Кожен об'єкт є кодом від оригінального CSS. Однак, на відміну від CSS, Web Animations API не потрібно призначати точні відсотки по анімації для кожного коду, що відкриває. Він автоматично розділить анімацію на рівні частини відповідно до кількості кодів, які ви даєте.Це означає, що об'єкт Keyframe з трьома кодами відтворюватиме середній код 50% часу через кожен цикл анімації, якщо не вказано інше.
Якщо ми хочемо, щоб певний набір коду зміщувався щодо іншого коду, ми можемо вказати зміщення безпосередньо на об'єкті який буде змінюватися, відокремивши значення коми. У наведеному прикладі видно, щоб колір Аліси змінювався на 30%, а не на 50% всього циклу, ми задаємо зсув: 0,333.
Там має бути як мінімум два кадри (що представляють початок та кінець анімації). Якщо у вашому списку keyframe тільки один запис, Element.animate(), то анімація виконуватися не буде, ви отримаєте помилку NotSupportedError exception.
І так повторимо, код рівномірно розподілений за умовчанням, якщо не вказано усунення. Зручно, чи не так?
Подання якості часу
Ми також повинні створити об'єкту тимчасові властивості (an AnimationEffectTimingProperties object), що відповідають значенню анімації Аліси:
Ви побачите тут кілька відмінностей того, як відповідні значення представлені у CSS:
- По-перше, тривалість у мілісекундах, на відміну від секунд – 3000, а не 3с. Як setTimeout і Window.requestAnimationFrame() , Web Animations API використовує лише мілісекунди.
- По-друге, ви помітили, що він ітераційний (повторюється), а чи не лічильник повторень.
Примітка: Існує низка невеликих відмінностей між термінологією, яка використовується в анімації CSS та термінології, яка використовується у веб-анімації. Наприклад, веб-анімації не використовується рядок "нескінченне", а натомість використовує JavaScript-код нескінченність. І замість тимчасової функції ми використовуємо ослаблення. Ми не будемо перераховувати тут значення послаблення, тому що, на відміну від CSS-анімації, де за замовчуванням animation-timing-function це просто, у веб-анімації API для послаблення за умовчанням використовується лінійна залежність - які ми використовуємо тут
Збираємо частини разом
Зараз зберемо всі частини разом, використовуючи Element.animate() метод:
document.getElementById("alice").animate(aliceTumbling, aliceTiming);
І вуаля, анімація працює (дивіться готовий варіант на version on Codepen).
The animate() метод може бути застосований на будь-який DOM-елемент, який може бути анімований за допомогою CSS. І він може бути записаний декількома способами. Замість того, щоб ділити об'єкти на ключові кадри та тимчасові характеристики, ми могли б просто передати свої значення безпосередньо так:
document.getElementById("alice").animate( [ < transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" >, < color: "#431236", offset: 0.333 >, < transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" >, ], < duration: 3000, iterations: Infinity, >, );
Більше того, якщо ми хотіли вказати лише тривалість анімації, а не її повторення (за замовчуванням анімації повторюється один раз), ми могли б пройтися тільки мілісекундами:
document.getElementById("alice").animate( [ < transform: "rotate(0) translate3D(-50%, -50%, 0)", color: "#000" >, < color: "#431236", offset: 0.333 >, < transform: "rotate(360deg) translate3D(-50%, -50%, 0)", color: "#000" >, ], 3000, );
Керування відтворенням за допомогою play(), pause(), reverse() and playbackRate
Хоча ми можемо писати CSS-анімацію з Web Animations API, де API дійсно добре підходить як вплив для відтворення анімації. Web Animations API забезпечує кілька зручних методів контролю відтворення анімації. Давайте подивимося на паузу та відтворення анімації в зростанні/зменшенні Аліси у грі (перевірити повний код можна на сайті full code on Codepen):
У цій грі Аліса змінюється у зростанні, вона то росте, то зменшується, а контролюємо ми цей процес за допомогою пляшки та кексу. Кожен із них мають свою анімацію.
Пауза та програвання анімації
Ми поговоримо про анімацію Аліси пізніше, а зараз подивимося ближче на анімації кексу:
var nommingCake = doc. : "steps(4, end)", тривалість: aliceChange.effect.timing.duration / 2, >, );
Метод Element.animate() буде виконуватися відразу ж як почнеться гра.
Тепер ми можемо запустити метод Animation.play() коли будемо готові:
Нам необхідно зв'язати його з анімацією Аліси, щоб вона росла щоразу, коли з'їдала кекс.
var growAlice = function() < // Play Alice's animation.
Коли користувач помістить вказівник миші вниз або натискає пальцем на торт на сенсорному екрані, ми можемо викликати growAlice, щоб виконати всі анімації:
cake.addEventListener("mousedown", growAlice, false);
Інші корисні методи
Крім паузи та відтворення, ми можемо використовувати такі методи анімації:
- Animation.finish() перейти до кінця анімації.
- Animation.cancel() перервати анімацію та видалити її ефект.
- Animation.reverse() встановлювати швидкість анімації якщо встановити ( Animation.playbackRate негативне значення, то анімація піде у зворотному порядку.
Давайте подивимося на перший playbackRate-негативне значення буде запускати анімацію у зворотному напрямку.
var shrinkAlice = function() < aliceChange.playbackRate = -1;
У Through the Looking-Glass, Аліса подорожує світом, де має бігти, щоб залишатися на місці і бігти вдвоє швидше, щоб рухатися вперед. Наприклад, у гонці з Червоною королевою, Аліса та Червона королева біжать, щоб залишатися на місці (перевірити повний код можна на full code on Codepen):
Так як маленькі діти легко втомлюються, на відміну від шахових постатей, Аліса постійно сповільнюється. Ми відобразили це у коді шляхом ослаблення (зменшення швидкості) playbackRate анімації.
setInterval(function () < // Make sure the playback rate never falls below .4 if (redQueen_alice.playbackRate >0.4) < redQueen_alice.playbackRate *= 0.9; >>, 3000);
Але постійно натискаючи на них мишею, ми змушуємо їх прискорити шляхом множення playbackRate (швидкості анімації)
var goFaster = function() < redQueen_alice.playbackRate *= 1.1; >; document.addEventListener("click", goFaster); document.addEventListener("touchstart", goFaster);
Фон також прискорюється при натисканні миші або торкання. Що ж відбувається, коли ви змушуєте Алісу та Червону королеву бігти вдвічі швидше? Що відбувається, коли вони гальмують?
Отримання інформації з анімації
Уявіть, що ми могли б використовувати playbackRate як покращення доступності сайту для користувачів з вестибулярними розладами, дозволяючи їм уповільнити анімацію на всіх сторінках сайту. Це неможливо зробити за допомогою CSS без перерахунку тривалості в кожному правилі CSS, але з веб-анімації API, ми могли б використовувати в майбутньому (поки не підтримується в браузерах!). швидкість анімації ось так:
document.getAnimations().forEach(function (animation) < animation.playbackRate *= 0.5; >);
З Web Animations API потрібно змінити лише одну властивість.
Інша справа, що це важко робити тільки з CSS Animations, створювати залежності від значення, передбачені для інших анімації.У прикладі гри про зростання і зменшення Аліси, ви можете помітити деякі дива у кексу:
тривалість: aliceChange.effect.timing.duration/2;
Щоб зрозуміти, що тут відбувається, погляньмо на анімацію Аліси:
var aliceChange = doc. ) scale(2)" >, ], < duration: 8000, easing: "ease-in-out", fill: "both", >,);
Зміна розміру Аліси вдвічі відбувається за 8 секунд. Потім ми зупиняємо її:
Якби залишили її на паузі на початку анімації, то Аліса збільшилася б удвічі, коли б випила всю пляшку. Ми хочемо зупинити її анімацію "відтворення" у середині, коли вона вже на половину виконана. Ми могли б це зробити, встановивши Animation.currentTime 4 секунди, ось так:
aliceChange.currentTime = 4000;
Але під час роботи над цією анімацією ми можемо збільшити її тривалість. Хіба не краще встановити динамічну зміну часу (currentTime), тоді нам не доведеться робити два оновлення за один раз. Ми можемо це зробити за допомогою посилання на зміну властивості розміру Аліси (aliceChange) Animation.effect який повертає всі деталі та діючі ефекти, що містяться в об'єкті, на Алісу:
aliceChange.currentTime = aliceChange.effect.timing.duration/2;
ефекти дозволяють нам отримати доступ до анімації keyframe (кадрів) і синхронності об'єктів - aliceChange.effect.timing , що вказує на час Алісиних елементів (які мають тип AnimationEffectTimingReadOnly) - в цьому міститься її AnimationEffectTimingReadOnly.duration. Ми можемо розподілити її тривалість на два рази, щоб отримати середню точку в часовій шкалі для встановлення нормального зростання.
Тепер ми можемо запустити її у зворотному порядку і грати анімацією в будь-якому напрямку, щоб змусити її рости або зменшуватися
var drinking = document. 2, >); drinking.pause();
І ми можемо зробити те саме при установці тривалості анімації на кексі або пляшці.
Тепер усі три анімації пов'язані лише з однією тривалістю, і ми можемо легко переходити з одного місця.
Ми також можемо використовувати веб-анімацію API, щоб з'ясувати Поточний час анімації. Гра закінчується, коли ви біжите від з'їденого торта або випитої пляшки. Зображення у гравця залежатиме від анімації Аліси. Чи стала вона надто великою на тлі крихітних дверей і не може в неї пройти або надто маленькою і не може дістати ключа, щоб відчинити двері. Ми можемо з'ясувати, чи стала вона великою або маленькою в кінці її анімація, отримуючи поточний час її анімації currentTime і розділивши її на activeDuration:
var endGame = function() < // get Alice's timeline's playhead location var alicePlayhead = aliceChange.currentTime; var aliceTimeline = aliceChange.effect.activeDuration; // stops Alice's і інші animations stopPlayingAlice(); // depending on third it falls into var aliceHeight = alicePlayhead/aliceTimeline; if (aliceHeight else if (aliceHeight >= .666) < // Alice got bigger! . >else < // Alice didn't change significantly . >>
Примітка: getAnimations() і ефект не повністю підтримуються на момент написання цієї статті, але polyfill підтримує їх вже сьогодні.
Колбеки та проміси
CSS Animations та Transitions (переходи) мають свої події і вони також можуть бути відтворені і в Web Animations API:
- onfinish це обробник події завершення анімації, він може бути запущений вручну за допомогою finish() .
- oncancel це обробник події скасування анімації, він може бути запущений вручну за допомогою методу cancel() .
Тут ми встановлюємо колбек для пляшки, кексу та Аліси, щоб запустити функцію endGame.
// When the cake or runs out.nommingCake.onfinish = endGame; drinking.onfinish = endGame; //. або Alice reaches end of her animation aliceChange.onfinish = endGame;
Подобається перспектива? Web Animations API також дає дві перспективи: onfinish і oncancel.
Примітка: Ці проміси не повністю підтримуються зараз.
Висновок
Такі основні особливості веб-анімації API, більшість з яких підтримується в останніх версіях Firefox і Chrome. До цього моменту ви повинні бути готові до "стрибка в кролячу нору" анімації в браузері та готові написати свої власні експерименти в анімації! Якщо ви використовуєте API і хочете поділитися, спробуйте використати хештег #WAAPI. Ми будемо стежити та писати інші підручники, щоб охопити майбутні додаткові функції, у вигляді підтримки поширюючи!
Подивіться також
- Повний набір Аліса в Країні Чудес
- Animateing like you just don't care with Element.animate — чудова стаття, щоб прочитати, де пояснюється більше на тлі веб-анімації API, і тому він є більш ефективним, ніж інші методи веб-анімації
- web-animations-js — the Web Animations API polyfill