Javascript как создать движущийся объект
Перейти к содержимому

Javascript как создать движущийся объект

  • автор:

JavaScript-анимации

С помощью JavaScript-анимаций можно делать вещи, которые нельзя реализовать на CSS.

Например, движение по сложному пути с временной функцией, отличной от кривой Безье, или canvas-анимации.

Использование setInterval

Анимация реализуется через последовательность кадров, каждый из которых немного меняет HTML/CSS-свойства.

Например, изменение style.left от 0px до 100px – двигает элемент. И если мы будем делать это с помощью setInterval , изменяя на 2px с небольшими интервалами времени, например 50 раз в секунду, тогда изменения будут выглядеть плавными. Принцип такой же, как в кино: 24 кадров в секунду достаточно, чтобы создать эффект плавности.

Псевдокод мог бы выглядеть так:

Более детальная реализация этой анимации:

Для просмотра примера, кликните на него:

Использование requestAnimationFrame

Теперь давайте представим, что у нас есть несколько анимаций, работающих одновременно.

Если мы запустим их независимо с помощью setInterval(. 20) , тогда браузеру будет необходимо выполнять отрисовку гораздо чаще, чем раз в 20ms .

Это происходит из-за того, что каждая анимация имеет своё собственное время старта и «каждые 20 миллисекунд» для разных анимаций – разные. Интервалы не выравнены и у нас будет несколько независимых срабатываний в течение 20ms .

…Меньше нагружают систему, чем три независимых функции:

Эти независимые перерисовки лучше сгруппировать вместе, тогда они будут легче для браузера, а значит – не грузить процессор и более плавно выглядеть.

Существует ещё одна вещь, про которую надо помнить: когда CPU перегружен или есть другие причины делать перерисовку реже (например, когда вкладка браузера скрыта), нам не следует делать её каждые 20ms .

Но как нам узнать об этом в JavaScript? Спецификация Animation timing описывает функцию requestAnimationFrame , которая решает все описанные проблемы и делает даже больше.

Такой вызов планирует запуск функции callback на ближайшее время, когда браузер сочтёт возможным осуществить анимацию.

Если в callback происходит изменение элемента, тогда оно будет сгруппировано с другими requestAnimationFrame и CSS-анимациями. Таким образом браузер выполнит один геометрический пересчёт и отрисовку, вместо нескольких.

Значение requestId может быть использовано для отмены анимации:

Функция callback имеет один аргумент – время прошедшее с момента начала загрузки страницы в миллисекундах. Это значение может быть получено с помощью вызова performance.now().

Как правило, callback запускается очень скоро, если только не перегружен CPU или не разряжена батарея ноутбука, или у браузера нет какой-то ещё причины замедлиться.

Код ниже показывает время между первыми 10 запусками requestAnimationFrame . Обычно оно 10-20 мс:

Структура анимации

Теперь мы можем создать более сложную функцию анимации с помощью requestAnimationFrame :

Функция animate имеет три аргумента, которые описывают анимацию:

Продолжительность анимации. Например, 1000 .

Функция расчёта времени, как CSS-свойство transition-timing-function , которая будет вычислять прогресс анимации (как ось y у кривой Безье) в зависимости от прошедшего времени ( 0 в начале, 1 в конце).

Например, линейная функция значит, что анимация идёт с одной и той же скоростью:

Это как если бы в transition-timing-function передать значение linear . Ниже будут представлены более интересные примеры.

Функция отрисовки, которая получает аргументом значение прогресса анимации и отрисовывает его. Значение progress=0 означает, что анимация находится в начале, и значение progress=1 – в конце.

Эта та функция, которая на самом деле и рисует анимацию.

Вот как она могла бы двигать элемент:

…Или делать что-нибудь ещё. Мы можем анимировать что угодно, как захотим.

Теперь давайте используем нашу функцию, чтобы анимировать свойство width от 0 до 100% .

Нажмите на элемент для того, чтобы посмотреть пример:

В отличие от CSS-анимаций, можно создать любую функцию расчёта времени и любую функцию отрисовки. Функция расчёта времени не будет ограничена только кривой Безье, а функция draw может менять не только свойства, но и создавать новые элементы (например, для создания анимации фейерверка).

Функции расчёта времени

Мы уже рассмотрели самый простой пример линейной функции расчёта времени выше.

Давайте посмотрим другие. Мы попробуем выполнить анимации с разными функциями расчёта времени, чтобы посмотреть как они работают.

Степень n

Если мы хотим ускорить анимацию, мы можем возвести progress в степень n .

Например, параболическая кривая:

Посмотрим в действии (нажмите для активации):

…Или кубическая кривая, или любой другой множитель n . Повышение степени увеличивает скорость анимации.

Вот график для функции progress в степени 5 :

Обратно: выстрел из лука

Эта функция совершает «выстрел из лука». В начале «натягивается тетива», а затем «выстрел».

В отличие от предыдущей функции, теперь всё зависит от дополнительного параметра x – «коэффициента эластичности». Он определяет силу «натяжения тетивы».

График для x = 1.5 :

Для анимации мы используем x с определённым значением. Пример для x со значением 1.5 :

Отскоки

Представьте, что мы бросили мяч вниз. Он падает, ударяется о землю, подскакивает несколько раз и останавливается.

Функции bounce делает то же самое, но в обратном порядке: «отскоки» начинаются сразу. Для этого заданы специальные коэффициенты:

Эластичная анимация

Ещё одна «эластичная» функция, которая принимает дополнительный параметр x для «начального отрезка».

График для x=1.5 :

В действии со значением x=1.5 :

Реверсивные функции: ease*

Итак, у нас получилась коллекция функций расчёта времени. Их прямое использование называется «easeIn».

Иногда нужно показать анимацию в обратном режиме. Преобразование функции, которое даёт такой эффект, называется «easeOut».

easeOut

В режиме «easeOut» timing функции оборачиваются функцией timingEaseOut :

Другими словами, мы имеем функцию «преобразования» – makeEaseOut , которая берет «обычную» функцию расчёта времени и возвращает обёртку над ней:

Например, мы можем взять функцию bounce описанную выше:

Таким образом, отскоки будут не в начале функции, а в конце. Смотрится гораздо лучше:

Ниже мы можем увидеть, как трансформации изменяют поведение функции:

Если раньше анимационный эффект, такой как отскоки, был в начале, то после трансформации он будет показан в конце.

На графике выше красным цветом обозначена обычная функция и синим – после easeOut .

  • Обычный скачок – объект сначала медленно скачет внизу, а затем резко подпрыгивает вверх.
  • Обратный easeOut – объект вначале прыгает вверх, и затем скачет там.

easeInOut

Мы можем применить эффект дважды – в начале и конце анимации. Такая трансформация называется «easeInOut».

Для функции расчёта времени, анимация будет вычисляться следующим образом:

В действии, bounceEaseInOut :

Функция «easeInOut» объединяет два графика в один: easeIn (обычный) для первой половины анимации и easeOut (обратный) – для второй половины.

Разница хорошо заметна, если сравнивать графики easeIn , easeOut и easeInOut для функции circ :

  • Красный обычный вариант circ ( easeIn ).
  • Зелёный – easeOut .
  • Синий – easeInOut .

Как видно, график первой половины анимации представляет собой уменьшенный easeIn , а второй – уменьшенный easeOut . В результате, анимация начинается и заканчивается одинаковым эффектом.

Более интересная функция «draw»

Вместо передвижения элемента мы можем делать что-нибудь ещё. Всё, что нам нужно – это правильно написать функцию draw .

Вот пример «скачущей» анимации набирающегося текста:

Итого

JavaScript может помочь в тех случаях, когда CSS не справляется или нужен жёсткий контроль над анимацией. JavaScript-анимации должны быть сделаны с помощью requestAnimationFrame . Это встроенный метод браузера, который вызывает переданную в него функцию в тот момент, когда браузер готовится совершить перерисовку (обычно это происходит быстро, но конкретные задержки зависят от браузера).

Когда вкладка скрыта, на ней совсем не происходит перерисовок, и функция не будет вызвана: анимация будет приостановлена и не потратит ресурсы. Это хорошо.

Вспомогательная функция animate для создания анимации:

  • duration – общая продолжительность анимации в миллисекундах.
  • timing – функция вычисления прогресса анимации. Получается момент времени от 0 до 1, возвращает прогресс анимации, обычно тоже от 0 до 1.
  • draw – функция отрисовки анимации.

Конечно, мы могли бы улучшить вспомогательную функцию и добавить в неё больше наворотов. Но JavaScript-анимации не каждый день используются, а только когда хотят сделать что-то интересное и необычное. Не стоит усложнять функцию до тех пор пока это вам не понадобились.

JavaScript-анимации могут использовать любые функции расчёта времени. Мы рассмотрели множество примеров и их вариаций, чтобы сделать их ещё более универсальными. В отличие от CSS, мы здесь не ограничены только кривой Безье.

То же самое и с draw : мы можем анимировать всё что угодно, не только CSS-свойства.

Как осуществить движение объектов в Javascript: инструкция с примерами

Lorem ipsum dolor

JavaScript изначально был созда н для того , чтобы осуществлять движение HTML-объектов на веб-страниц ах . Это его призвание и основная сфера деятельности. Для тех , кто не знает, JavaScript — это самый популярный язык веб-разработки, при помощи которого можно организовать любой вид анимации на веб-сайте.

Частичн о о рганизовать движение объектов на веб-странице можно, используя CSS-свойства. С приходом CSS 3 т аблица стилей сильно расширила свои возможности , п оэтому сделать простую анимацию при помощи CSS сейчас не проблема. То ест ь з аставить объект «дергаться», «пульсировать», «крутиться» и друго е м ожно при помощи CSS , и в большинстве случае в и спользование CSS будет предпочтительней, потому что таблица стилей потребляет меньше ресурсов браузера, чем JavaScript-скрипт.

Однак о б олее сложное движение объектов на страниц е о рганизовать без JavaScript не получится. Поэтому сегодня мы покажем, как можно заставить объекты HTML двигаться при помощи JavaScript.

Движение объектов при помощи JavaScript

Движение объектов — это последовательность из кадров, в которых меняются HTML и CSS свойства. Например, если изменять «style.left» в диапазоне «0рх – 150рх» — это и будет движение объекта. При этом нужно задать «плавность» или «интервал» , в котором будут сменяться кадры, чтобы эффект движения выглядел реалистичным. Например , в нашем случа е м ожно изменять положение объекта на «2рх» с интервалом 30 раз в секунду. В JavaScript за это отвечает «setInterval»

Чтобы добиться реалистичности, нужно помнить принцип кинематографа: 24 кадр а в секунду — это эффект реалистичности движения. В нашем случа е к од JavaScript мог бы быть таким:

<script>

//определяем старт движения объекта по клику на него

object.onclick = function() <

let start = Date.now(); // запоминаем время, когда начинается движение

let timer = setInterval(function() <

// определяем количество времени со старта движения

let timePassed = Date.now() — start;

if (timePassed >= 1500) <

clearInterval(timer); // заканчиваем движение через 1 , 5 секунды

return;

>

// отрисовываем движение на момент «timePassed», который прошел со старта движения объекта

draw(timePassed);

>, 24);

// пока «timePassed» отчисляет время от 0 до 1500 миллисекунд

// «left» корректирует «пиксельное» значение объекта

function draw(timePassed) <

object.style.left = timePassed / 3 + ‘px’;

>

</script>

В представленном выше коде у нас будет некий HTML-объект «object». Если на него «кликнуть», тогда он начнет движение влево. При этом нужно не забыть объявить этот объект в документе HTML.

Более сложное движение HTML-объектов

  1. «duration» — указывает продолжительность движения ;

  2. «timing(timeFraction)» — функция, которая рассчитывает время и прогресс движения ;

  3. «draw(progress)» — функция, которая отрисовывает движение объекта.

Заключение

Чтобы организовать движение объекто в т огда , когда не справляется CSS, вам придется использовать JavaScript. Движение объектов в JavaScript ничем не ограничен о . Сегодня мы показали малую часть возможностей JS, но , даже если ими «поиграться» , изменя я значения аргументов, тогда можно будет сотворить что угодно.

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

Простые анимации

Поскольку для управления элементами <canvas> используется JavaScript, не составляет труда сделать (интерактивные) анимации. В этой главе мы рассмотрим, как делаются некоторые базовые анимации.

Вероятно, самым большим ограничением является то, что когда фигура нарисована, её уже нельзя двигать. Чтобы изобразить движение нам нужно перерисовать фигуру и всё, что было нарисовано до неё. Перерисовка сложных кадров занимает много времени, и производительность сильно зависит от скорости компьютера, на котором она выполняется.

Основные шаги анимации

Ниже перечислены необходимые шаги для того, чтобы нарисовать кадр:

  1. Очистить canvas Если фигура, которую вы собираетесь нарисовать, не занимает всю площадь canvas (как фон, например), то всё что было нарисовано ранее необходимо стереть. Проще всего это сделать при помощи метода clearRect() .
  2. Сохранить изначальное состояние canvas Если вы изменяете любые настройки (такие как стили, трансформации и т.п.), которые затрагивают состояние canvas и вы хотите убедиться, что оригинальное состояние используется каждый раз, когда был отрисован кадр, то вам следует сохранить это оригинальное состояние.
  3. Нарисовать анимированные фигуры Шаг на котором вы собственно отрисовываете кадр.
  4. Восстановить состояние canvas Если вы сохраняли состояние, восстановите его, прежде чем отрисовывать новый кадр.

Управление анимацией

Фигуры отрисовываются на canvas либо напрямую — при помощи методов canvas, либо с помощью сторонних функций. В нормальной ситуации результат станет виден на canvas после окончания выполнения скрипта. К примеру, цикл for использовать для анимации нельзя.

Это значит, нужен способ выполнения функций отрисовки через интервалы времени. Есть два способа для управления такой анимацией.

Запланированные обновления

Первый — это функции window.setInterval() (en-US), window.setTimeout() (en-US), и window.requestAnimationFrame() , которые могут быть использованы для вызова некоторой функции, через заданный промежуток времени.

Начинает периодически исполнять функцию function каждые delay миллисекунд.

Запускает выполнение указанной функции function через delay миллисекунд.

Сообщает браузеру, что вы хотите выполнить анимацию, и запрашивает, чтобы браузер вызвал указанную функцию callback для обновления анимации перед следующей перерисовкой.

Если вы не планируете никакого взаимодействия с пользователем, вы можете использовать функцию setInterval() , которая многократно выполняет, предоставленный ей код. Если же вы планируете создать игру, в которой контроль анимации осуществляется мышью или клавиатурой, то необходимо использовать setTimeout() . Установив EventListener , вы можете перехватываете любые действия пользователя и запустить соответствующие функции анимации.

Примечание: В примерах ниже мы будем использовать функцию window.requestAnimationFrame() для контроля анимации. Функция requestAnimationFrame является более эффективной для создания анимации, так как новая итерация вызывается, когда система готова к отрисовке нового кадра. Количество вызовов в секунду примерно равно 60 и уменьшается, когда вкладка неактивна. Для более подробного изучения цикла анимации, особенно для игр, прочитайте статью Анатомия видеоигр В Зоне разработке игр.

Анимированная солнечная система

В этом примере анимируется небольшая модель солнечной системы.

Screenshot Live sample

Анимированные часы

В этом примере создаются анимированные часы, показывающие правильное время.

Screenshot Live sample

Зацикленная панорама

В этом примере панорама прокручивается слева направо. Мы используем фото национального парка Йосемити взятое из Википедии, но вы можете использовать любое изображение, большее элемента canvas.

Заметьте, что ширина и высота должны совпадать со значениями CanvasXZSize и CanvasYSize .

Другие примеры

Хороший пример того, как сделать управляемую анимацию с клавиатуры.

Мы рассмотрим некоторые продвинутые методы анимации и физику в следующей главе.

Основы “плавности”

Анимации — важная часть создания привлекательных веб-приложений и сайтов. Пользователи ожидают высокую отзывчивость и интерактивность.

В классической анимации движение, скорость которого в начале низкая, а затем увеличивается, называется “slow in” (смягчение в начале движения), а движение, скорость которого в начале высокая, а затем уменьшается ― “slow out” (смягчение в конце движения). В Интернете эти варианты движения называются “ease in” (ускорение) и “ease out” (замедление). Иногда используется сочетание двух этих вариантов — “ease in out” (ускорение в начале — замедление в конце). Отсюда понятно, что изменение скорости ― это процесс, направленный на смягчение анимации.

Плюсы: плавность благодаря своей простой анимации придает приложению естественность.

Плавность для простой анимации используется со свойством CSS transition . Например, transition можно использовать для того, чтобы кнопка плавно изменяла цвет фона при наведении ( hover ). Базовый переход фонового цвета выглядит следующим образом:

В CSS можно использовать следующие ключевые слова:

  • linear
  • ease-in
  • ease-out
  • ease-in-out

Примечания:

  1. Анимации без плавности называются линейными.
  2. Ease-in анимации начинаются медленно и заканчиваются быстро.
  3. Ease-out анимации начинаются быстро и заканчивается медленно.
  4. Анимация сразу с двумя ключевыми словами in и out похожа на ускорение и замедление автомобиля и может придать довольно интересный эффект.

Анимации с помощью CSS и JavaScript

Есть два основных способа создания анимации в браузере: с помощью языков CSS и Javascript. А какой из них лучше выбрать? Все зависит от особенностей проекта. Вот советы, которые помогут принять решение:

  1. Используйте CSS, если у вас небольшие автономные состояния для UI-элементов.
  2. Используйте JavaScript, если хотите больше контроля над анимациями.
  3. Используйте requestAnimationFrame для организации анимаций вручную. Он говорит браузеру о том, что вы хотите выполнить анимацию и передаете ему обратный вызов, который нужно осуществить до следующего обновления страницы. Подробнее о requestAnimationFrame на MDN можно узнать здесь.

Анимации с помощью CSS

Анимация с помощью CSS — это самый простой способ создания движения на экране. Этот подход является декларативным, поскольку необходимо указать, что именно должно произойти.

При использовании CSS анимация определяется независимо от целевого элемента и используется свойство animation (или комбинация его под-свойств) для создания необходимой анимации и дальнейшего ее использования в сочетании с @keyframes .

Чтобы CSS-анимации работали в устаревших версиях браузеров необходимо добавить вендорные префиксы. Советую использовать postcss.

Пример кода можно найти здесь.

Анимации с помощью JavaScript/TypeScript

Создать анимации с помощью JavaScript сложнее, чем с CSS, однако разработчик получает больший контроль. Узнать об API веб-анимации можно здесь.

JavaScript/TypeScript анимации являются императивными.

Примечание: API веб-анимации поддерживается в современных браузерах. При отсутствии поддержки доступен полифил.

Пример кода можно найти здесь.

Советы по анимации

  1. По возможности используйте анимации на CSS, а не на JavaScript, поскольку движок браузера способен оптимизировать их раньше времени с помощью графического процессора.
  2. Ease-out анимация зачастую является правильным выбором и хорошим значением по умолчанию. Она быстро запускается и делает анимации более отзывчивыми, добавляя красивое замедление в конце.
  3. На easings.net можно найти больше формул плавности.
  4. Длительность ease-out анимации должна составлять около 200–500 мс — оптимальное время для восприятия анимации глазом.
  5. Длительность ease-in анимации также должна составлять около 200–500 мс. В конце будет присутствовать резкая остановка анимации, и никакие изменения времени не смягчат ее.
  6. Основное правило — быстрая реакция на действия со стороны пользователя.
  7. Новичкам следует использовать библиотеки для обработки анимационных задач, такие как GSAP, anime.js, animate.css и многие другие.
  8. Используйте свойство CSS will-change , чтобы браузер знал, что именно вы планируете анимировать.

Пример: анимация модального представления

Модальные представления предназначены для важных сообщений, а также сообщений, в которых представлены причины блокировки пользовательского интерфейса. Однако слишком часто применять их не стоит.

В демонстрации ниже создадим пример модального окна в проекте Angular.

Код CSS для анимирования модального окна:

Здесь можно найти весь исходный код.

Производительность CSS-анимации

Свойства анимации не бесплатны, и анимировать некоторые из них дешевле, чем другие. СЛЕДУЕТ избегать запуска каких-либо геометрических изменений или рисунков, поскольку при наличии множества элементов на странице они обойдутся дорого.

Это значит, что анимация будет ограничена ТОЛЬКО уровнем прозрачности ( opacity ) или трансформацией ( transform ).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *