JavaScript изначально был создан для того, чтобы осуществлять движение HTML-объектов на веб-страницах. Это его призвание и основная сфера деятельности. Для тех, кто не знает, JavaScript — это самый популярный язык веб-разработки, при помощи которого можно организовать любой вид анимации на веб-сайте.
Частично организовать движение объектов на веб-странице можно, используя CSS-свойства. С приходом CSS3 таблица стилей сильно расширила свои возможности, поэтому сделать простую анимацию при помощи 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-объектов
В первом примере мы показали простое движение объекта в одном направлении с одинаковой скоростью. Но бывают движения объектов по более сложному алгоритму. Например, когда над одним объектом происходит несколько одновременных типов анимации.
Любое движение объектов с помощью JavaScript — это дополнительная нагрузка на браузер и на процессор компьютера, поэтому к формированию движения объектов необходимо подходить более ответственно. Например, когда нужно анимировать несколько разных объектов одним видом анимации, тогда лучше использовать одну сгруппированную функцию для всех объектов, нежели несколько отдельных функций для каждого отдельного объекта. То есть лучше вот так:
setInterval(function() {
objectMovement1();
objectMovement2();
objectMovement3();
}, 24)
Вот так будет хуже, и это съест больше ресурсов браузера:
setInterval(objectMovement1, 24)
setInterval(objectMovement2, 24)
setInterval(objectMovement3, 24)
Для создания сложного движения объектов в JavaScript присутствует много функций. Одна из таких — это «requestAnimationFrame()».
Так может выглядеть код сложного анимационного движения объектов:
<script>
object.onclick = function animate({timing, draw, duration}) {
let start = performance.now();
requestAnimationFrame(function animate(time) {
// «timeFraction», будет изменяться в диапазоне «0 – 1»
let timeFraction = (time - start) / duration;
if (timeFraction > 1) timeFraction = 1;
// вычисляем текущее состояние движения объекта
let progress = timing(timeFraction);
draw(progress); // отрисовываем движение
if (timeFraction < 1) {
requestAnimationFrame(animate);
}
});
}
</script>
Если взглянуть внимательно на код, тогда видно, что функция «animate» имеет 3 аргумента, описывающих движение нашего объекта «object». Это:
«duration» — указывает продолжительность движения;
«timing(timeFraction)» — функция, которая рассчитывает время и прогресс движения;
«draw(progress)» — функция, которая отрисовывает движение объекта.
На самом деле, наиболее интересная функция из этих трех — это «timeFraction». Добавляя к ней правильные аргументы, можно контролировать визуальный эффект движения объекта. Например, можно ускорить анимацию, если добавить такой код:
function quad(timeFraction) {
return Math.pow(timeFraction, 3)
}
Чем больше будет числовой аргумент, тем быстрее будет передвигаться объект. Числовой аргумент показывает, на сколько нужно умножить стандартную скорость движения объекта.
Если хотите, чтобы объект медленно набирал скорость, но потом резко ускорялся (двигался по «дуге»), тогда можно применить такой вид функции:
function circ(timeFraction) {
return 1 - Math.sin(Math.acos(timeFraction));
}
Если хотите, чтобы объект слегка откатился назад, а потом резко начал набирать скорость по подобию стрельбы из лука, тогда можно применить такой код функции:
function back(x, timeFraction) {
return Math.pow(timeFraction, 2) * ((x + 1) * timeFraction - x)
}
Если нужно, чтобы объект двигался как баскетбольный мяч, отскакивая от края контейнера, тогда можно применить вот такой код функции:
function bounce(timeFraction) {
for (let a = 0, b = 1; 1; a += b, b /= 2) {
if (timeFraction >= (7 - 4 * a) / 11) {
return -Math.pow((11 - 6 * a - 11 * timeFraction) / 4, 2) + Math.pow(b, 2)
}
}
}
Заключение
Чтобы организовать движение объектов тогда, когда не справляется CSS, вам придется использовать JavaScript. Движение объектов в JavaScript ничем не ограничено. Сегодня мы показали малую часть возможностей JS, но, даже если ими «поиграться», изменяя значения аргументов, тогда можно будет сотворить что угодно.
JavaScript