Для Хактоберфеста в этом году я участвовал в проекте, используя элемент <canvas>. Я был заинтригован, так как сталкивался с этим раньше, когда изучал HTML, но всегда думал: Эх, однажды я до этого доберусь….

Что такое элемент <canvas>?

Это элемент HTML, который дает вам возможность рисовать с помощью JavaScript. Довольно аккуратно. Он принимает любые id и размеры, которые вы хотите, в качестве атрибутов и оборачивает резервное изображение, которое отображается только в том случае, если ваш чертеж не загружается:

Как оживить луну

Вам не нужно анимировать элемент <canvas>, но я подумал, что это будет хорошей задачей. Я решил создать анимацию прибывающей и убывающей луны. Мой подход заключался в том, чтобы написать функцию для каждой фазы и прокрутить их, используя setTimeout().

Заложить фундамент

Прежде всего, каждый элемент <canvas> должен начинаться с двух вещей:

Сначала мы выбираем элемент <canvas> в HTML с его id и сохраняем его в переменной. Во-вторых, мы создаем переменную для контекста. Это то, что мы на самом деле рисуем. Сюрприз! Сам элемент <canvas> на самом деле является просто контейнером. Именно эту переменную контекста мы будем использовать в наших функциях.

Инициализировать

Я выбрал полумесяц в качестве начальной фазы. Я нарисовал его с помощью функции init() и добавил как атрибут к элементу <body>, который мы видели ранее, чтобы он вызывался при загрузке страницы.

Повторить с небольшими вариациями

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

  1. в этом()
  2. четверть Луны ()
  3. месяц()
  4. полнолуние()
  5. половина MoonWane ()
  6. четвертьMoonWane()

Каждая функция вызывает следующую, а quarterMoonWane() вызывает init(). Именно так достигается непрерывный эффект прироста/угасания. Единственные различия заключаются во внутренней (безье) и внешней (дуговой) кривых каждой фазы. На самом деле это только четыре функции, так как quarterMoon() и halfMoon() в основном эквивалентны quarterMoonWane() и halfMoonWane(). Я повторил их, потому что на этапе затухания мне нужны были те же формы, но разные setTimeout() вызовы функций.

Проблемы и размышления

Элемент <canvas> — это не шутка. Я потратил два дня на то, чтобы понять, как добиться этой анимации. Конечно, это была моя первая попытка, и мне пришлось провести много исследований, проб и ошибок со сложной математикой, но работать с этим элементом по-прежнему сложно. Несмотря на то, что я рад, что познакомился с ним, я не могу представить ситуацию, в которой мне захотелось бы использовать его снова.

Одна из самых сложных вещей заключается в том, что вы не можете видеть свой прогресс, пока не вызовете метод для соединения установленных вами точек (здесь я использовал ctx.fill(), вы можете использовать ctx.stroke(), чтобы нарисовать линию вместо). Было неудобно делать это после каждой строки, а затем удалять их все (кроме последней), когда я знал, что происходит. Это заставляет меня задаться вопросом, есть ли более простой способ.

Я также очень хотел, чтобы переход между этапами был немного более плавным. Я попытался ускорить интервалы на setTimeout(), но это не дало того эффекта, на который я надеялся. Я также экспериментировал с window.requestAnimationFrame(), еще одним методом, используемым с <canvas>, но он сам по себе делал его слишком быстрым. Я уверен, что есть способ заставить его работать, но я не смог найти его после долгих поисков и экспериментов.

Наконец, поскольку здесь много повторяющегося кода, я уверен, что есть более элегантный способ добиться такого типа анимации, но, в конце концов, он выполняет свою работу, и я его поклонник!

Вот ресурс для получения дополнительной информации об элементе <canvas> и, как всегда, вот мой код, если вы хотите изучить его более подробно.

Первоначально опубликовано на https://dev.to 11 октября 2021 г.