HTML5 / Рисуем на холсте или Где же Да Винчи 2.0

в 11:56, , рубрики: canvas, html5, web 2.0, метки: , ,

HTML5 / Рисуем на холсте или Где же Да Винчи 2.0
Доброго времени суток!
Введение

Только ленивый никогда не открывал какой-либо графический редактор, чтобы нарисоввать что-нибудь. Все мы этим занимались. Да и сейчас занимаемся. Только вот графические редакторы представляют собой исполняемые файлы, а хочется открыть страничку в браузере и начать рисовать, после чего сохранить результат на тот же сайт.
И с приходом HTML5 у нас такая возможность появилась!
new Canvas() ?

Для того, чтобы рисовать на холсте, сначала мы должны объявить элемент Canvas в разметке нашей страницы с некоторыми атрибутами, среди которых width — высота и height — ширина нашего холста. Объявление будет выглядеть следующим образом:

Внутри элемента мы должны создать абзац, который пользователь увидит в том случае, если его браузер не поддерживает Canvas. Например, мы попросим его обновить браузер.

Вот такое предупреждение мы рискуем увидеть:
Не увидели? Поехали дальше!
Получаем холст в рабство в своё распоряжение

Следующим необходимым шагом является получение 2D контекста Canvas, чтобы в дальнейшем мы имели возможность работать с ним. Нам же от него только это и нужно?. Тут на помощь нам приходит JavaScript:
var canv = document.getElementById("canv"); // получаем ссылку на элемент
var ctx = canv.getContext("2D"); // получаем контекст

Вот, собственно, и всё.
И это работает?

Да, абсолютно. Давайте убедимся в этом, придав элементу canvas подобный стиль:
#canv {
border: 1px black dotted;
border-radius: 10px;
}

И откроем наш браузер. В случае успешной инициализации мы увидим следующее:
Рисуем, сегодня мы с тобой рисуем!

Итак, холст находится полностью в нашем распоряжении. Давайте что-нибудь нарисуем. Линию. Нет проблем:
ctx.strokeStyle = "black"; // указываем цвет
ctx.lineWidth = "5"; // устанавливаем ширину линии
ctx.moveTo(0,0); // устанавливаем кисть в позицию (0;0)
ctx.lineTo(100,100); // рисуем линию от (0;0) до (100;100)
ctx.lineTo(300,200); // рисуем линию от (100;100) до (300;200)
ctx.stroke(); // показываем изменения на экране

Результат не замедлил сказаться:
Разбор полётов

Но давайте-ка разберёмся в том, почему для такой тривиальной задачи, как отрисовка линии понадобилось пять строк кода. Нет, ну хорошо — четыре. Давайте разберём код по порядку.
ctx.strokeStyle = "black";

Здесь мы указываем кисти, что нужно рисовать чёрным цветом. На самом деле существует ещё один style-атрибут, который указывает цвет — fillStyle, который указывает кисти, что (!!!) цвет заливки должен быть, например, красным. А strokeStyle указывает кисти на то, каким цветом мы должны отрисовывать границу или линию, что в принципе одно и то же.
ctx.lineWidth = "5";

Тут всё просто до безобразия — указываем ширину нашей линии.
ctx.moveTo(0,0);

Здесь всё намного интереснее. В данном случае мы указываем начальное положение кисти, из которого и будет происходить отрисовка линии.
ctx.lineTo(100,100);

А отрисовываем линию мы как раз до этого положения на координатной прямой. Стоит заметить, что каждый раз move'ить не обязательно. Например, если вам нужно нарисовать первую линию, а сразу же из точки конца сделать точку начала второй линии, то можно просто stro'чить.
ctx.lineTo(300,200);

Без комментариев… Просто-напросто рисуем вторую линию.
ctx.stroke();

Отображаем нарисованное на холсте. Казалось бы, всё просто, но и тут разработчики намудрили. Пьянству бой!. stroke() необходимо использовать лишь для тех примитивов, которые в начале названия имеют stroke (например, strokeRect).
В случае, если мы не воспользуемся этим методом, то отрисованного во внеэкранном буфере мы не увидим. Тут сразу вспоминается ситуация с двойной буферизацией в J2ME.
WTF?

Там ситуация обстоит аналогичная, но она касается всех графических примитивов. Вот так, например, мы можем осуществить отрисовку на GameCanvas:
protected void run() { // отрисовка выполняется по запуску треда
Graphics g = getGraphics(); // получаем ссылку на объект Graphics для работы с примитивами
w = getWidth(); // получаем высоту экрана
h = getHeight(); // получаем ширину экрана
g.setColor(Graphics.BLACK); // ставим цвет кисти
g.drawLine(0,0,w,h); // рисуем линию
flushGraphics(); // отображаем изменения на холсте
}

Я сделал комментарии к коду, так что вам он должен быть понятен. Ситуации со stroke() аналогичная.
feelings fill'ings

Но этот метод используется не везде. Например, для отрисовки закрашенного прямоугольника он не нужен:
ctx.fillStyle = "aqua";
ctx.fillRect(20,20,100,100);
ctx.fillStyle = "silver";
ctx.fillRect(100,100,200,200);
ctx.fillStyle = "red";
ctx.fillRect(150,150,250,250);

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

Вот так в пару шагов мы можем рисовать в окне нашего браузера. В следующей части мы более детально ознакомимся с тем, что можно отрисовывать, какие трансформации можно применять и т.д.
Продолжение следует! А пока рекоммендую вам почитать вот это и это.

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js