Перед тим як ми перейдемо до вирішення, давайте ближче розглянемо проблему. CSS властивості animation і transition обмежують нас рухом тільки по прямій. Як це відбувається? Завжди вибирається найкоротший шлях від точки А до точки В. Відмінно же - в більшості випадків цього достатньо - проте ми не можемо сказати CSS пройтися «красивим шляхом», а не «найкоротшим».
Найпростіший спосіб в CSS анімації від однієї точки до іншої (з апаратним прискоренням) це властивість transform зі значенням translate. Таким чином можна отримати рух уздовж прямої. У @keyframes блоці нижче ми рухаємося вгору і вниз з точки (0, 0) в точку (100, -100), як в прикладі вище:
Це нескладно, але давайте зупинимося. Щоб зрозуміти, як вирішити нашу задачу, необхідно хоча б візуально розбити нашу анімацію на частини.
Практичний курс по верстці адаптивного Лендінзі з нуля!
Навчіться з нуля верстати адаптивні Лендінзі на HTML5 та CSS3 за найближчі 6 днів
У 0% об'єкт знаходиться в точці (0, 0), на 50% ми використовуємо translate3D (100px, -100px, 0) для переміщення в точку (100, -100), потім переміщаємося назад. Перефразовуючи, ми рухаємо об'єкт на 100px вправо і потім на 100px вгору. Два переходу разом рухають об'єкт у верхній кут.
Рішення: одна функція на вісь
Так як же створити рух по кривій, як показано вище? Щоб об'єкт рухався не по прямій лінії необхідно, щоб швидкість пересування по осях Х і У була різною.
У попередніх прикладах всюди використовувалася функція linear, однак якщо обернути наш об'єкт в контейнер, то одну функцію можна застосувати для пересування по Х, а іншу для пересування по У. Нижче ми використовуємо ease-in для осі Х і ease-out для У:
Реалізація: один об'єкт на вісь
На жаль, ми не можемо поставити кілька властивостей transform, застосовано буде тільки останнє. Так як же насправді поєднати дві анімації? Ми помістимо один об'єкт всередину іншого і запустимо одну анімацію для контейнера, а іншу для дочірнього елемента.
У всіх прикладах вище з рухається точкою уздовж кривої ви бачили, як анімації піддавалися два елементи, а контейнер був цілком прозорий. Щоб зрозуміти, як два об'єкти взаємодіють між собою, і як виходить рух по кривій, ми зробили видимим контейнер за допомогою значення border-box:
Точка розташовується всередині боксу і рухається разом з ним по осі Х, в той час як сама точка переміщається по осі У. Якщо прибрати рамку контейнера, то ми отримаємо пересування по кривій. Замість використання двох об'єктів в HTML можна додати псевдоклас. Якщо HTML виглядає так:
Можна додати псевдоклас:
Нам потрібно два окремі блоки анімації: один для осі Х, інший для У. Зверніть увагу, як в першому блоці використовується ease-in, а в другому ease-out:
Додамо Вендорний префікси для WebKit браузерів і парочку кривих Безьє замість ease-in і ease-out, і у нас вийде приклад, показаний на початку статті:
Код призведе нас до того, з чого ми почали.
Ви, мабуть, вже помітили, що у всіх прикладах ми використовували @keyframes анімацію. Однак це тільки тому, що нам потрібно було рухати точку назад і вперед. Якщо необхідно пересунути об'єкт з точки А в точку В, шарувата анімація добре працює з властивістю transition.
Якщо об'єкт позиційований абсолютно, анімувати по кривій лінії його можна за допомогою властивостей left і bottom. В такому випадку вам знадобиться тільки один об'єкт, контейнер додавати не треба. Тим не менш, є причина, по якій слід уникати такої анімації: продуктивність такої анімації дуже низька, і вона промальовується на кожному кадрі заново. Шарувата ж анімація з псевдоклас і апаратним прискоренням властивості translate робить пересування дуже плавним, не знижуючи продуктивність.
Редакція: Команда webformyself.
Практичний курс по верстці адаптивного Лендінзі з нуля!
Навчіться з нуля верстати адаптивні Лендінзі на HTML5 та CSS3 за найближчі 6 днів
Найсвіжіші новини IT і веб-розробки на нашому Telegram-каналі