и
>top
можно использовать для абсолютного позиционирования относительно левого верхнего угла ближайшего включающего его элемента, у которого
>position
не равно
>static
. А если такого элемента нет, тогда он позиционируется относительно документа.
Мы можем использовать это для создания анимации. Следующий документ показывает картинку с котом, которая двигается по эллипсу.
>
> 
>
>
> var cat = document.querySelector("img");
> var angle = 0, lastTime = null;
> function animate(time) {
> if (lastTime != null)
> angle += (time - lastTime) * 0.001;
> lastTime = time;
> cat.style.top = (Math.sin(angle) * 20) + "px";
> cat.style.left = (Math.cos(angle) * 200) + "px";
> requestAnimationFrame(animate);
> }
> requestAnimationFrame(animate);
>
Картинка отцентрирована на странице и ей задана >position: relative
. Мы постоянно обновляем свойства >top
и >left
картинки, чтобы она двигалась.
Скрипт использует >requestAnimationFrame
для вызова функции >animate
каждый раз, когда браузер готов перерисовывать экран. Функция >animate
сама опять вызывает >requestAnimationFrame
, чтобы запланировать следующее обновление. Когда окно браузера (или закладка) активна, это приведёт к обновлениям со скорость примерно 60 раз в секунду, что позволяет добиться хорошо выглядящей анимации.
Если бы мы просто обновляли DOM в цикле, страница бы зависла и ничего не было бы видно. Браузеры не обновляют страницу во время работы JavaScript, и не допускают в это время работы со страницей. Поэтому нам нужна >requestAnimationFrame
– она сообщает браузеру, что мы пока закончили, и он может заниматься своими браузерными вещами, например обновлять экран и отвечать на запросы пользователя.
Наша функция анимации передаётся текущее время через аргументы, которое оно сравнивает с предыдущим (переменная >lastTime
), чтобы движение кота было однородным, и анимация работала плавно. Если бы мы просто передвигали её на заданный промежуток на каждом шаге, движение бы запиналось если бы, например, другая задача загрузила бы компьютер.
Движение по кругу осуществляется с применением тригонометрических функций >Math.cos
и >Math.sin
. Я кратко опишу их для тех, кто с ними незнаком, так как они понадобятся нам в дальнейшем.
>Math.cos
и >Math.sin
полезны тогда, когда надо найти точки на круге с центром в точке (0, 0) и радиусом в единицу. Обе функции интерпретируют свой аргумент как позицию на круге, где 0 обозначает точку с правого края круга, затем нужно против часовой стрелки, пока путь диной в 2π (около 6,28) не проведёт нас по кругу.