Элементарный Canvas +15



Если вы изучаете веб совсем недавно, но уже успели увидеть различные красивые эффекты на сайте, по типу системы частиц или какие либо игры разработанные на canvas'e и вас это заинтриговало, но изучать что-то новое очень страшно, то я вам готов продемонстрировать, как за 50 строк js кода можно сделать что-то интересное на canvas'e.

image

Скажу сразу, я хочу объяснить логику работы с canvas'ом. Код очень простой, я надеюсь, это подтолкнет вас к изучению такого инструментария как canvas. А так же это очень хорошая практика для начинающего JS программиста.

Перейдем к коду. Напишем простую генерацию квадратов разного цвета на полотне. Код вы можете увидеть сразу весь, далее я объясню его.


Что нам нужно сделать?

  1. Получить canvas и его 2D контекст (Если вы раньше не делали подобного, то не переживайте, это делает 2-мя строчками кода)
  2. Сделаем наш канвас немного адаптивным
  3. Зададим нужные нам переменные и свойства
  4. Отрисовка элемента на canvas'e
  5. При ресайзе меняем размер канваса

Работу в canvas можно разделить на 3 этапа.

  1. Настройка нужных нам свойств (толщина пера, цвет заливки, цвет линии и прочие свойства)
  2. Рисуем элемент
  3. Если мы делаем что-то динамическое. Например, игру, анимацию, систему частиц и прочие элементы, то создаем цикл и в него закидываем рендер (отрисовку) наших объектов

Ну хорошо, вернемся к нашему коду.

1. Как я и говорил, две строчки кода и мы можем манипулировать полотном

image

Получить элемент по Id это стандартный API браузера, а вот getContext это метод самого canvas'a. Можно получить и 3D контекст, но в данный момент он нам не нужен.

2. Второй пункт, третий и пятый я объединю т.к. идет объявление переменных + код здесь одинаковый. Можно даже сделать отдельную функцию т.к. уже идет дублирование кода, а это плохо.

image

Переменные width и height нам потребуются дальше.Также не забудьте вызвать функцию ReSize после получения контекста canvas'а.

Нам потребуется еще объект options. В нем мы будем хранить все настройки.

opacity — скорость с которой наши элементы будут затираться на canvas'e
count — количество кубов, которые мы будем создавать за один прогон функции
fps — думаю объяснять не нужно для чего… правда работает странно…
color — здесь лежит маска, которая представляет нашу цветовую палитру
hue — это цветовой тон в диапазоне от 0 до 360. На картинку будет понятней

image

divisionSpeed — это переменная с помощью которой мы сможем регулировать скорость смены цвета

image

4. Нам остается лишь создать цикл, функцию для отрисовки и вызвать всё это.

image

Создаем функцию Init, она нужна для инициализации цикла. У window есть отличный метод requestAniimationFrame() который позволяет зациклить вызов нужной нам функции. Так же внутри Init мы вызываем функцию Step() в которой и хранится код отрисовки наших кубиков.

Отрисовку мы будем делать в цикле, чтобы отрисовывать сразу 100 элементов. Внутри цикла, первым же делом мы ставим условие, которое позволяет нам выбрать цветовой тон в диапазоне от 0 до 360, тем самым цвета наших кубиков будут меняться. Две последующие строчки можно объединить в одну, тем самым напрямую задать цвет заливки фигуры. ctx.fillStyle позволяет задать цвет заливки, а ctx.fillRect(точка x, точка y, ширина, высота) позволяет нарисовать фигуру. Задаем рандомную высоту с шириной, но в диапазоне наших размеров.

Две строчки после цикла, это для очистки экрана. Вы уже знаете, что fillstyle позволяет задать цвет заливки, мы задаем белый цвет с прозрачностью равной opacity из объекта options. А так же запускаем отрисовку очищающей фигуры из точки 0:0 с размерами равными размерам нашего canvas'a.

Нам остается только вызвать функцию Init в любом месте нашей программы.

Если вы все еще сомневаетесь, что можно делать красивые вещи с помощью canvas, то вот вам один из примеров.


Если вас заинтересовал canvas, то самое время продолжить изучение этой технологии. Я не могу вам посоветовать хорошую статью по изучению т.к. для меня было очень скучно читать про canvas и для себя я ничего хорошего не сохранил в закладки. А на youtube очень мало хороших видео по canvas'у, а те что и можно посмотреть содержат лишь 10% нужной инфы и 30% воды, а всё остальное время пишут код с ошибками и проектируют его на ходу. На мой взгляд, самое лучшее это взять какой-то простой пример и попытаться самому его реализовать.

Вы можете помочь и перевести немного средств на развитие сайта



Комментарии (20):

  1. sfi0zy
    /#19604462

    Думаю лучше все-таки в статьи вставлять код в виде кода, а не картинками.

    • Maklaud
      /#19604732

      Код в виде кода скопируют и забудут, а с картинки придется напечатать вручную — лучше усвоится :)

      Пример с гравитацией просто офигенный, автор молодец!

      • StrangerInTheKy
        /#19606168 / +1

        Код на картинке нельзя найти по ctrl+F!
        Читаешь-читаешь длинную статью, потом в конце статьи «а помните в начале мы использовали функцию my_stupid_function_on_picture»… Да-да, помню, сейчас пролистаю наверх и прочитаю все надписи на картинках еще раз, но очень-очень внимательно…

    • EpicLegend_gg
      /#19605700

      Сужу по себе, код из статьи я копирую… я не пишу его сам. А потом и удивляюсь… а почему я не понимаю то, что я якобы написал… Вот из-за этого и картинки вставил.

      • AngReload
        /#19605762

        На некоторых числах if(options.hue == 360) options.hue = 0; никогда не выполнится, надо использовать >=.
        И это условие должно идти после сложения.
        Цвет в любом случае меняется, hue == 361 будет интерпретирован как hue == 1, но всё-таки это ошибка.
        Лучше использовать остаток от деления:


        options.hue += 1 / options.divisionSpeed;
        options.hue %= 360;

        • EpicLegend_gg
          /#19605870

          Спасибо. Насчет >= верно(эта погрешность осталась от того момента, когда я использовал целые числа), но % здесь не нужен. Да и менять перед проверкой также лишнее т.к. результат будет идентичный тому, который есть сейчас.

  2. Zenitchik
    /#19604914

    Переменные width и height нам потребуются дальше.

    В глобальном пространстве имён? Вы серьёзно?

    Также не забудьте вызвать функцию ReSize после получения контекста canvas'а.

    Зачем? Она же не работает с контекстом.

    • EpicLegend_gg
      /#19605694

      Я не пишу библиотеку, которой потом «возможно» будут пользоваться. Это простой пример. Лучше допускать ошибки, чем не писать вовсе код.

      ReSize нужно один раз вызвать перед основным циклом т.к. он установит нужные размеры канвасу и обновит значения переменных width и height

      • Zenitchik
        /#19606082 / +1

        Это простой пример.

        Сразу содержащий плохой пример…

        Лучше допускать ошибки, чем не писать вовсе код.

        Как PET-проект — может быть, но не как совет другим.

        ReSize нужно один раз вызвать перед основным циклом

        Именно, и это не обязательно
        после получения контекста canvas'а.


        Я лично рекомендую его запускать сразу после загрузки страницы.

        • Keyten
          /#19606188

          Да не так уж и плохо, например в jsfiddle в маленьких демках тоже вполне допустимо юзать глобальные переменные типа width / height.

  3. tamerlan676
    /#19605692

    На сервисе udacity есть курс по Canvas. Вполне себе достойный.

  4. muhaa
    /#19605874 / +7

    Если вас заинтересовал canvas, то самое время продолжить изучение этой технологии.

    1. Функции для рисования графики были и есть в любой мало-мальски развитой среде разработки, начиная с бейсика или Турбо-паскаля в 80-ых.
    2. Эти функции для рисования во всех средах реализуются почти одинаковым и очевидным образом, Canvas — не исключение.
    3. Для освоения функций рисования графики в любой среде разработки, достаточно почитать документацию с пол-часа.
    На фоне всего этого про Canvas периодически пишут статьи, в которых Canvas подается как новая крутая технология а не в духе «основы программирования для чайников».
    Та же тенденция наблюдалась и в других случаях веб-разработки: «революционный» json (мы можем просто перечислить поля объекта через запятую!), прорывной Ajax (мы можем запросить данные с сервера!), REST…

    Я к чему это все. Уважаемые начинающие веб-программисты, поймите, что вещи уровня Canvas, Json, Ajax — это очень очень просто и очевидно. Важность и новизна подобных «технологий» заключалась в том, чтобы ввести их в браузер, который является достоянием всего человечества. Сами по себе они тривиальны.

    • EpicLegend_gg
      /#19606072

      Так а кто спорит? Я полностью с вами согласен.
      Нет на ру сегменте нормального образования.(ну или я их не встречал) За основы программирования подаются переменные, функции, ветвление, циклы.

    • Zenitchik
      /#19606096 / +1

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

      Так статьи и пишутся про их реализацию в браузере. Будь они хоть трижды тривиальны, но чтобы применить конкретную их реализацию — нужно знать API пресловутой реализации.
      То же самое могу сказать об Ajax.

      Что же касается данной конкретной статьи — ценность её нулевая, потому что то же самое легко находится поиском по Хабру, причём лучше написанное (и, что характерно, очень давно).

  5. StrangerInTheKy
    /#19606158 / +1

    opacity — скорость с которой наши элементы будут затираться на canvas'e
    Opacity — это непрозрачность, а не скорость.

  6. set
    /#19606286

    fps — думаю объяснять не нужно для чего… правда работает странно…

    Думаю, объяснять надо. Я так и не понял, где именно используется это свойство. Оно объявлено, но нигде не вызывается.

    ctx.fillStyle позволяет задать цвет заливки, а ctx.fillRect(точка x, точка y, ширина, высота) позволяет нарисовать фигуру. Задаем рандомную высоту с шириной, но в диапазоне наших размеров.

    В описании вы говорите о задании рандомных размеров, но ведь в коде написаны рандомные координаты, но статичные размеры. Где ошибка-то? В описании или в реализации?

    • Bhudh
      /#19607314

      Просто во фразе «Задаем рандомную высоту с шириной» автором разумеются координата x («ширина») и координата y («высота»).

      • set
        /#19607970

        Простите, но зачем же подменять понятия? Ведь в цитируемом сообщении автор изначально указывает, какие свойства передаются методу и в какой очерёдности — «точка x, точка y, ширина, высота». И практически сразу же пишет о рандомной ширине и высоте.