Вы здесь: Главная » JavaScript » Тег canvas. Рисование на холсте в JavaScript

Тег canvas. Рисование на холсте в JavaScript

Тег <canvas> появился HTML5, но с точки зрения управления им, как тегом или записи для него css-свойств он малоинтересен. Смысл его использования виден только при применении JavaScript, т.к. именно код на JS способен оживить и анимировать рисунке на холсте (канве).

Тег <canvas> в какой-то степени похож на <svg> - он тоже дает по умолчанию прямоугольную область размером 300x150px и предназначен для рисования программными  методами. Но в <svg> это происходит с помощью вложенных тегов, а в <canvas> - с помощью JS-кода.  Как правило, для тега <canvas> задают атрибут id:

Также можно изменить размеры прямоугольной области <canvas> с помощью атрибутов width и height:

Ни в первом, ни во втором случае вы не увидите этой прямоугольной области, если выше/ниже него нет текста или пока не заданы css-свойства в виде background или border, т.к. canvas - это прозрачный по умолчанию элемент:

Также в css можно управлять размерами холста с помощью css-свойств width и height.

Теперь мы видим, где расположен наш тег <canvas>:

Можно сказать, что холст (canvas) представляет собой прямоугольную область на экране, в которой вы можете рисовать фигуры - прямоугольники или круги, линии - прямые и изогнутые, изображения и даже текст. Первыми, кто внедрил canvas была фирма  Apple, и этот элемент прижился настолько,  что попал в стандарт HTML5. Еще ранее подобные инструменты существовали во Flash (сейчас ее заменила Adobe Animate) в языке ActionScript, который базируется на тех же стандартах EcmaScript, что и JavaScript для браузеров. Кстати, та же компания Apple, которая вывела canvas на html-страницы, изрядно поспособствовала пропаже с них flash-роликов.

В отличие от SVG - формата векторной графики - canvas позволяет рисовать с помощью пикселей, а не векторных кривых. Поэтому и возможности этих 2-х форматов отличаются. SVG - это набор тегов, каждым из которых можно управлять и с точки зрения CSS, и с точки зрения управления DOM-структурой в JavaScript. А canvas - это набор команд, которыми вы будете преимущественно управлять из JavaScript. Хотя есть ряд возможностей, которые доступны и в SVG, и в Canvas, что делает их похожими. На одной и той же html-странице  вы можете использовать и тег (и) <svg>, и тег(и) <canvas>, и даже накладывать их друг на друга с помощью CSS.

Сейчас нам надо будет разобраться с рисованием на canvas, и начнем с простых фигур, которые в графических программах называют примитивами.

  1. Рисуем прямоугольники
  2. Рисуем линии
  3. Рисуем дуги вместо кругов

Рисуем прямоугольники в canvas

Для рисования на canvas для начала нужно обратиться к самому элементу. Проще и быстрее всего это сделать с помощью метода document.getElementById('some-id'). А затем сохранить в переменную (например, context) ссылку на двухмерный контекст методом  getContext('2d').

Рисование прямоугольника предполагает использование метода context.fillRect(x, y, width, height):

В примере ниже на холсте в 500x200px мы нарисовали прямоугольник 400x200px с заливкой зеленого цвета, сместившись на 50px вправо и на 50px вниз.

Примечание: для того чтобы можно было ориентироваться в координатах, для canvas был добавлен фон в виде сетки с шагом в 50px, которую вы можете скачать для собственных экспериментов.

Также для создания прямоугольника без заливки, только с контуром, используется метод:

Для того чтобы стереть прямоугольник, нужен метод:

Этот метод может также использоваться, чтобы стереть все, что нарисовано на вашем холсте:

С помощью всех 3-х методов можно сделать рамку вместо прямоугольника.

Код примера:

Обратите внимание, что в коде использованы еще 2 метода:

Эти методы задают цвет заливки и обводки в canvas. Если вы этого не делаете, то по умолчанию цвет заливки и контура будет черным, и это видно на примере первых прямоугольников. Можно задавать цвет любым способом, доступным в CSS: "red", "#ff0000", "rgb(255,0,0)", "rgba(255,0,0,0.5)", а также использовать градиенты и текстуры в виде изображений.

Для управления толщиной линии (контура) используется свойство lineWidth (по умолчанию равно 1px):

Рисуем линии, или пути (path), в canvas

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

Аналогично выполняется процесс и в JavaScript (и в его брате ActionScript). Поэтому в canvas существуют методы, подобные действиям в программах. Сначала мы перемещаемся в точку с координатами x, y, ничего пока не рисуя:

Затем создаем прямую линию, идущую от тех координат, которые мы задали в moveTo(x,y) до новых координат x1, y1 в методе lineTo():

Этот метод может быть вызван любое количество раз в зависимости от того, какая вам нужна фигура. Учтите, что рисование начинается с точки, указанной в moveTo() и продолжается до точки с координатами в методе lineTo(), причём конечная точка первой линии (пути)  является начальной точкой второй линии и т. д.  Можно использовать метод moveTo(), чтобы перенестись в другую точку.

Для создания контура сначала нужно указать его начало методом:

Выполняем обводку фигуры, добавляя к ней контур:

Выполняем заливку фигуры:

Закрываем контур:

Для фигур  с заливкой закрывать контур (путь) необязательно - это сделает заливка по кратчайшему расстоянию между двумя соседними точками. Для фигуры с одной обводкой нужно либо закрыть контур (context.closePath()), либо дорисовать контур до начальной точкой методом lineTo(xstart, ystart).

Нарисуем елку:

В начале и в конце пути мы указали, что мы начинаем (метод beginPath()) и заканчиваем (метод closePath()) контур (путь), а в середине перемещались к определенным координатам методом moveTo() и проводили линии методом lineTo().  Чтобы увидеть контуры нам понадобился метод stroke(), а заливку добавим, раскомментировав последнюю строку context.fill() (в примере ниже кликнув на кнопку).


У контуров есть еще ряд свойств:

Свойство/МетодЗначениеНазначение
lineCap"butt" | "round" | "square"Устанавливает внешний вид концов линий
lineJoin"bevel" | "round" | "miter" (по умолчанию)Устанавливает внешний вид углов, которые получаются при соединении линий
miterLimitПоложительное числоОпределяет максимальную длину среза линий в месте соединения. Если текущая длина среза будет превышать заданное значение, то угол будет отображаться как при значении "bevel" свойства lineJoin
setLineDash(массив)Массив чисел [линия, пропуск]Определяет размер линий и пустых мест в пунктирной линии
getLineDash()возвращает массив чисел [линия, пропуск]Возвращает массив чисел для линий и пустых мест в пунктирной линии
lineDashOffsetЧисло с плавающей запятой (0.0 по умолчанию)Указывает, где следует начинать тире массива в строке.

Пример со свойством lineJoin

Результат: сначала "bevel", затем "round" и за ним "mitter".

Пример со свойством lineCap

Для демонстрации различных концов наших линий нарисуем сначала направляющие, которые определяют начало и конец каждого отрезка, а затем уже сами линии-отрезки. обратите внимание, что 2 последних варианта свойства lineCap приводят к увеличению длины отрезка.

Результат: сначала "butt", затем "round" и за ним "square".

Пример использования методов setLineDash() и getLineDash() для рисования пунктирных линий

При создании пунктирных линий имеет смысл использовать в массиве, передаваемом в метод setLineDash() 2, 4, 6 параметров (т.е. четное их количество), чтобы линия получилась красивой.

В этом примере для последней линии было используется свойство lineDashOffset, которое смещает начало линии на указанное количество пикселей так, как это показано на картинке:

Свойство lineDashOffset для canvas

С помощью свойства  lineDashOffset можно создать "марширующих муравьев", которые в Photoshop, например, показывают область выделения. Код для  их создания таков:

Результат:

Рисуем дуги вместо круга в canvas

К сожалению, с кругом (овалом) далеко не так все просто, как в графических программах или в svg. В canvas не получится нарисовать circle, т.к. здесь доступно создание дуги (arc), которая имеет центр с координатами в x,y, начало, заданное углом startAngle, и конец, заданный углом endAngle (оба угла задаются в радианах), а также логический параметр true|false, который говорит о том, создается ли дуга против или по ходу часовой стрелки (по умолчанию используется параметр по ходу часовой стрелки):

Стоит остановится на углах. В отличие от css-свойства tranform: rotate(45deg), в котором, в основном, используются градусы, для arc используются радианы. Один радиан - это значение π, которое равно примерно 3.14. Ему соответствует угол в 180 ° и константа математического класса Math в JavaScript - Math.PI. Поэтому, мы можем использовать эту константу, чтобы рассчитывать углы. Придется вспомнить слегка курс школьной алгебры или геометрии или использовать такую формулу для перевода градусов в радианы:

Пробуем на примере нарисовать 2 круга с заливкой и с контуром. Последний параметр является необязательным, поэтому во втором случае мы его опускаем - и тоже получаем круг.

Пример вживую:

Не всегда нужно нарисовать полный круг, поэтому рассмотрим пример, где дугу можно нарисовать размером в 120°. Разница между двумя дугами заключается в рисовании по (120°) и против часовой стрелки(240°) , а также в заливке полученной фигуры и заливке только контура.

Рисуем дугу с заданными контрольными точками и радиусом, соединяя эти точки прямой линией.

В этом случае нам понадобятся касательные линии.

Выглядит этот код, как голова животного

Автор: Админ

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *