Для Хактоберфеста в этом году я участвовал в проекте, используя элемент <canvas>
. Я был заинтригован, так как сталкивался с этим раньше, когда изучал HTML, но всегда думал: Эх, однажды я до этого доберусь….
Что такое элемент <canvas>
?
Это элемент HTML, который дает вам возможность рисовать с помощью JavaScript. Довольно аккуратно. Он принимает любые id
и размеры, которые вы хотите, в качестве атрибутов и оборачивает резервное изображение, которое отображается только в том случае, если ваш чертеж не загружается:
Как оживить луну
Вам не нужно анимировать элемент <canvas>
, но я подумал, что это будет хорошей задачей. Я решил создать анимацию прибывающей и убывающей луны. Мой подход заключался в том, чтобы написать функцию для каждой фазы и прокрутить их, используя setTimeout()
.
Заложить фундамент
Прежде всего, каждый элемент <canvas>
должен начинаться с двух вещей:
Сначала мы выбираем элемент <canvas>
в HTML с его id
и сохраняем его в переменной. Во-вторых, мы создаем переменную для контекста. Это то, что мы на самом деле рисуем. Сюрприз! Сам элемент <canvas>
на самом деле является просто контейнером. Именно эту переменную контекста мы будем использовать в наших функциях.
Инициализировать
Я выбрал полумесяц в качестве начальной фазы. Я нарисовал его с помощью функции init()
и добавил как атрибут к элементу <body>
, который мы видели ранее, чтобы он вызывался при загрузке страницы.
Повторить с небольшими вариациями
В итоге у меня получилось шесть очень похожих функций, настолько похожих, что я не буду подробно описывать каждую из них:
- в этом()
- четверть Луны ()
- месяц()
- полнолуние()
- половина MoonWane ()
- четвертьMoonWane()
Каждая функция вызывает следующую, а quarterMoonWane()
вызывает init()
. Именно так достигается непрерывный эффект прироста/угасания. Единственные различия заключаются во внутренней (безье) и внешней (дуговой) кривых каждой фазы. На самом деле это только четыре функции, так как quarterMoon()
и halfMoon()
в основном эквивалентны quarterMoonWane()
и halfMoonWane()
. Я повторил их, потому что на этапе затухания мне нужны были те же формы, но разные setTimeout()
вызовы функций.
Проблемы и размышления
Элемент <canvas>
— это не шутка. Я потратил два дня на то, чтобы понять, как добиться этой анимации. Конечно, это была моя первая попытка, и мне пришлось провести много исследований, проб и ошибок со сложной математикой, но работать с этим элементом по-прежнему сложно. Несмотря на то, что я рад, что познакомился с ним, я не могу представить ситуацию, в которой мне захотелось бы использовать его снова.
Одна из самых сложных вещей заключается в том, что вы не можете видеть свой прогресс, пока не вызовете метод для соединения установленных вами точек (здесь я использовал ctx.fill()
, вы можете использовать ctx.stroke()
, чтобы нарисовать линию вместо). Было неудобно делать это после каждой строки, а затем удалять их все (кроме последней), когда я знал, что происходит. Это заставляет меня задаться вопросом, есть ли более простой способ.
Я также очень хотел, чтобы переход между этапами был немного более плавным. Я попытался ускорить интервалы на setTimeout()
, но это не дало того эффекта, на который я надеялся. Я также экспериментировал с window.requestAnimationFrame()
, еще одним методом, используемым с <canvas>
, но он сам по себе делал его слишком быстрым. Я уверен, что есть способ заставить его работать, но я не смог найти его после долгих поисков и экспериментов.
Наконец, поскольку здесь много повторяющегося кода, я уверен, что есть более элегантный способ добиться такого типа анимации, но, в конце концов, он выполняет свою работу, и я его поклонник!
Вот ресурс для получения дополнительной информации об элементе <canvas>
и, как всегда, вот мой код, если вы хотите изучить его более подробно.
Первоначально опубликовано на https://dev.to 11 октября 2021 г.