Главная страница 1


Veebikujundus Natalia Prishvitsyna

Давайте порисуем в HTML5

Top of Form

Bottom of Form

Оригинал: http://diveintohtml5.info/canvas.html

В HTML5 определен элемент 

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

Поддержка

IE

Firefox

Safari

Chrome

Opera

iPhone

Android

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

* Internet Explorer поддерживает только с библиотекой explorercanvas.

Как же этот холст выглядит? В действительности, никак. У тега 

 нет собственного контента и рамки.



http://htmlbook.ru/sites/default/files/images/html5/canvas01.png

Невидимый холст

Код выглядит так.



Давайте добавим пунктирную рамку, чтобы увидеть, с чем мы имеем дело.



холст с рамкой

Холст с рамкой

У вас может быть несколько элементов 

 на одной странице. Каждый холст будет отображаться в DOM и сохранять свое собственное состояние. Если вы добавите каждому холсту атрибут id, то можете получить к ним доступ, как и к любому другому элементу.

Расширим наш код, включив атрибут id.

Теперь легко можно обнаружить элемент 

 в DOM.

var a_canvas = document.getElementById("a");

Простые формы



IE

Firefox

Safari

Chrome

Opera

iPhone

Android

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

* Internet Explorer поддерживает только с библиотекой explorercanvas.

Каждый холст изначально пустой. Это скучно! Давайте что-нибудь нарисуем.



http://htmlbook.ru/sites/default/files/images/html5/4145.png

Событие onclick вызывает эту функцию:

function draw_b() {
  var b_canvas = document.getElementById("b");
  var b_context = b_canvas.getContext("2d");
  b_context.fillRect(50, 25, 150, 100);
}

Первая строка функции не делает ничего особенного, она просто находит элемент

 в DOM.

function draw_b() {
  var b_canvas = document.getElementById("b");
  var b_context = b_canvas.getContext("2d");
  b_context.fillRect(50, 25, 150, 100);
}

Каждый холст имеет контекст рисования, в котором и происходят все эти смешные штучки. Как только вы нашли элемент 

 в DOM (с помощью document.getElementById() или любым другим способом), вызываете метод getContext(). Необходимо указать строку"2D" в методе getContext().



Спроси профессора Маркапа

☞В. Есть холст 3D?

О. Пока нет. Отдельные производители экспериментируют с собственным трехмерным API, но ни один из них не стандартизирован. В спецификации HTML5 отмечено: «в будущих версиях данной спецификации, вероятно, будет определен 3D-контекст».

Итак, у вас есть элемент 

 и есть контекст рисования, где определены методы и свойства рисования. Имеется целая группа свойств и методов посвященных рисованию прямоугольников.



  • Свойство fillStyle может быть цветом, рисунком или градиентом (подробнее о градиентах чуть ниже). По умолчанию fillStyleзаливает сплошным черным цветом, но вы можете установить что угодно. Каждый контекст рисунка помнит свои собственные свойства при открытии страницы, пока вы ее не обновите.

  • fillRect(x, y, width, height) рисует прямоугольник, заполненный текущим стилем заливки.

  • Свойство strokeStyle как и fillStyle может быть цветом, рисунком или градиентом.

  • strokeRect(x, y, width, height) рисует прямоугольник с текущим стилем линии. strokeRect не заливается внутри, он просто рисует границы.

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

Спроси профессора Маркапа

☞В. Можно ли «перезагрузить» холст?

О. Да. Установка ширины или высоты для элемента 

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

var b_canvas = document.getElementById("b");


b_canvas.width = b_canvas.width;

Вернемся к предыдущему примеру.



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

var b_canvas = document.getElementById("b");


var b_context = b_canvas.getContext("2d");
b_context.fillRect(50, 25, 150, 100);

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

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

Вызов метода fillRect() рисует прямоугольник и заполняет его текущим стилем заливки, исходно черный цвет, пока вы его не измените. Прямоугольник задается левым верхним углом (50, 25), шириной (150) и высотой (100). Чтобы лучше представить, как это работает, давайте посмотрим на систему координат.

Координаты холста

Холст это двумерная сетка. Координата 0,0 находится в левом верхнем углу холста. Вдоль оси X значения растут к правому краю холста. По оси Y значения растут к нижнему краю холста.



координаты холста

Координаты холста

Координатная сетка была нарисована с помощью 

 и включает в себя:



  • набор серых вертикальных линий;

  • набор серых горизонтальных линий;

  • две черные горизонтальные линии;

  • две черные вертикальные линии;

  • две маленькие черные диагональные линии, которые образуют стрелки;

  • две черные вертикальные линии;

  • две маленькие черные диагональные линии, которые образуют вторую стрелу;

  • букву «х»;

  • букву «у»;

  • текст «(0, 0)» вблизи левого верхнего угла;

  • текст «(500, 375)» в нижнем правом углу;

  • точку в левом верхнем углу и другую в нижнем правом углу.

Во-первых, нам необходимо определить сам элемент  , задать ему ширину и высоту, а также id, чтобы мы могли найти его позже.

Тогда мы должны найти сценарий 

 элемент в DOM и получить его в контекст рисования.

var c_canvas = document.getElementById("c");
var context = c_canvas.getContext("2d");

Теперь мы можем рисовать линии.

Контуры


IE

Firefox

Safari

Chrome

Opera

iPhone

Android

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

* Internet Explorer поддерживает только с библиотекой explorercanvas.

http://htmlbook.ru/sites/default/files/images/html5/7563.png

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

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

Чтобы рисовать прямые линии карандашом, можно использовать следующие два метода:



  1. moveTo(х, у) перемещает карандаш к указанной начальной точке.

  2. lineTo(х, у) рисует линии до указанной конечной точки.

Чем чаще вы вызываете moveTo() и lineTo(), тем длиннее получается контур. Это «карандашные» методы — вы можете обращаться к ним так часто, насколько хотите, но вы ничего не увидите на холсте, пока не обратитесь к одному из «чернильных» методов.

Давайте нарисуем серую сетку.



Рисование вертикальных линий

for (var x = 0.5; x < 500; x += 10) {


context.moveTo(x, 0);
context.lineTo(x, 375);
}

Рисование горизонтальных линий

for (var y = 0.5; y < 375; y += 10) {


context.moveTo(0, y);
context.lineTo(500, y);
}

Это все были «карандашные» методы. На самом деле, на холсте еще ничего не нарисовано, нам нужны «чернильные» методы, чтобы сделать рисунок видимым.

context.strokeStyle = "#eee";
context.stroke();

stroke() является одним из «чернильных» методов. Он принимает сложный контур, заданный всеми вызовами moveTo() и lineTo(), и рисует его на холсте. strokeStyle управляет цветом линии. Вот результат.



сетка

 

Спроси профессора Маркапа

☞В. Почему мы начинаем x и y c 0.5, а не с 0?

О. Представьте каждый пиксел как большой квадрат. Все целочисленные координаты (0, 1, 2, ...) являются углами этих квадратов. Если вы рисуете однопиксельную линию между целыми координатами, она будет перекрывать противоположные стороны пиксельного квадрата, в результате будет нарисована ширина два пиксела. Чтобы нарисовать  линию шириной только в один пиксел, необходимо сместить координаты на 0.5 перпендикулярно к направлению линии.

К примеру, если вы попытаетесь нарисовать линию от (1, 0) до (1, 3), браузер будет рисовать линию с перекрытием в полпиксела по обе стороны от x=1. На экране невозможно отобразить половину пиксела, поэтому линия будет расширена для покрытия двух пикселов.

линия от (1,0) до (1,3) толщиной два пиксела

Если вы попробуете нарисовать линию от (1.5, 0) до (1.5, 3), браузер нарисует линию с перекрытием полпиксела на каждой стороне от x=1.5, что в результате дает истинную однопиксельную линию.



линия от (1.5,0) до (1.5,3) толщиной один пиксел

Спасибо Джейсону Джонсону за эти графики.

Теперь нарисуем горизонтальную стрелку. Все линии и кривые на контуре нарисованы тем же цветом (или градиентом — да, мы скоро до него доберемся). Мы хотим нарисовать стрелку другим цветом — черным, а не серым, так что мы должны начать новый контур.

Новый контур

context.beginPath();
context.moveTo(0, 40);
context.lineTo(240, 40);
context.moveTo(260, 40);
context.lineTo(500, 40);
context.moveTo(495, 35);
context.lineTo(500, 40);
context.lineTo(495, 45);

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



Не новый контур

context.moveTo(60, 0);


context.lineTo(60, 153);
context.moveTo(60, 173);
context.lineTo(60, 375);
context.moveTo(65, 370);
context.lineTo(60, 375);
context.lineTo(55, 370);

Я сказал, что эти стрелки будут черными, но strokeStyle установлен в серый (fillStyle и strokeStyle не сбрасываются, когда вы начинаете новый контур). Это нормально, потому что мы просто запустили серию «карандашных» методов. Но прежде чем нарисовать реально в «чернилах», мы должны установить strokeStyle черным. В противном случае эти две стрелки будут серыми, и мы вряд ли их заметим. Следующие строки изменяют цвет на черный и рисуют линии на холсте.

context.strokeStyle = "#000";
context.stroke();

Вот результат.



сетка со стрелками

Текст


IE

Firefox

Safari

Chrome

Opera

iPhone

Android

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

* Internet Explorer поддерживает только с библиотекой explorercanvas.

В дополнение к рисованию линий на холсте, вы также можете нарисовать текст. В отличие от текста окружающей веб-страницы, здесь нет боксовой модели. Это означает, что нет знакомых из CSS техник верстки: нет плавающих элементов, нет отступов, нет полей, нет переноса слов (хотя вы можете считать все это хорошей вещью). Вы можете установить несколько атрибутов шрифта, выбрать точку на холсте и нарисовать текст.

Следующие атрибуты шрифта доступны в контексте рисования.


  • font может содержать все, что вы бы добавили в свойство CSS font. Включает стиль шрифта, насыщенность, размер, межстрочное расстояние и семейство гарнитур.

  • textAlign управляет выравниванием текста. Похоже на свойство CSS text-align, но не идентично ему. Возможные значения: start,end, left, right и center.

  • textBaseline говорит где рисуется текст относительно начальной точки. Возможные значения: top, hanging, middle, alphabetic,ideographic и bottom.

Атрибут textBaseline хитрый, потому что сам текст такой (к тексту на английском это не относится, но вы ведь можете нарисовать любой символ Юникода). Спецификация HTML5 объясняет различия между базовыми линиями.

Верх площадки em (top) это примерно верх глифов в шрифте; выносная базовая линия (hanging) там, где привязаны некоторые глифы вроде आ; середина (middle) это половина между верхом и низом площадки em; алфавитная базовая линия (alphabetic) проходит там, где привязаны символы вроде Á, ÿ, f и Ω; идеографическая базовая линия (ideographic) располагается там, где привязаны символы вроде и ; низ площадки em это примерно низ глифов в шрифте. Верх и низ ограничивающего прямоугольника может быть далеко от базовой линии из-за того, что глифы выходят далеко за пределы прямоугольника em.



базовые линии

Для простых алфавитов вроде английского вы можете без опасений придерживаться значений top, middle или bottom у свойстваtextBaseline.

Давайте нарисуем какой-нибудь текст! Текст внутри холста наследует размер шрифта и стиль  самого элемента

, но вы можете переопределить эти значения, установив свойства шрифта в контексте рисования.

Изменение стиля шрифта

context.font = "bold 12px sans-serif";
context.fillText("x", 248, 43);
context.fillText("y", 58, 165);

Метод fillText рисует собственно текст.

context.font = "bold 12px sans-serif";


context.fillText("x", 248, 43);
context.fillText("y", 58, 165);

Спроси профессора Маркапа

☞В. Могу ли я использовать относительные размеры шрифтов для рисования текста на холсте?

О. Да. Как и любой другой HTML-элемент на странице, 

 сам вычислит размер шрифта на основе правил CSS. Если вы установите свойство context.font на относительный размер шрифта, такой как 1.5em или 150%, ваш браузер умножит его на вычисленный размер шрифта самого элемента  .

Для текста в левом верхнем углу, скажем, хочу, чтобы верх текста был при y=5. Но я ленивый, не хочу измерять высоту текста и вычислять базовую линию. Вместо этого я установлю textBaseline как top и укажу координаты левого верхнего угла окружающего текст прямоугольника.

context.textBaseline = "top";
context.fillText("( 0 , 0 )", 8, 5);

Теперь текст в правом нижнем углу. Скажем, я хочу в правом нижнем углу текст, который будет в точке с координатами (492, 370) — это всего несколько пикселов от правого нижнего угла холста — но я не хочу измерять ширину или высоту текста. Я могу установитьtextAlign как right и textBaseline как bottom, а затем вызвать fillText() с координатами правого нижнего угла прямоугольника ограничивающего текст.

context.textAlign = "right";
context.textBaseline = "bottom";
context.fillText("( 500 , 375 )", 492, 370);

И вот результат.



http://htmlbook.ru/sites/default/files/images/html5/canvas10.png

Упс! Мы забыли точки в углах. Мы увидим, как рисовать окружности чуть позже. Пока же я немного схитрю и нарисую их в виде прямоугольников.



Рисуем две точки

context.fillRect(0, 0, 3, 3);


context.fillRect(497, 372, 3, 3);

И это все что написано! Вот финальный результат.



http://htmlbook.ru/sites/default/files/images/html5/canvas11.png

Градиенты



Градиент

IE

Firefox

Safari

Chrome

Opera

iPhone

Android

Линейный

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

Радиальный



3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

* Internet Explorer поддерживает только с библиотекой explorercanvas.

Ранее в этой главе вы узнали, как нарисовать прямоугольник заполненный цветом, затем как обводить линию заданным цветом. Но формы и линии не ограничены сплошным цветом, вы можете воспользоваться всеми видами магии с градиентами. Давайте посмотрим на примере.

Разметка выглядит так же, как любой другой холст.

Вначале мы должны обнаружить элемент 

 и его контекст рисования.

var d_canvas = document.getElementById("d");
var context = d_canvas.getContext("2d");

После того как мы задали контекст, можем определить градиент. Градиент это плавный переход между двумя или более цветами. Контекст рисования холста поддерживает два типа градиента:



  1. createLinearGradient(x0, y0, x1, y1) рисует вдоль линии от (x0, y0) до (x1, y1).

  2. createRadialGradient(x0, y0, r0, x1, y1, r1) рисует по конусу между двумя окружностями. Первые три параметра определяют начальную окружность с центром (x0, y0) и радиусом r0. Последние три параметра представляют последнюю окружность с центром (x1, y1) и радиусом r1.

Давайте сделаем линейный градиент. Градиенты могут быть любого размера, но я сделаю этот градиент шириной 300 пикселей, как и холст.

Создание градиентного объекта

var my_gradient = context.createLinearGradient(0, 0, 300, 0);

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

После того как мы получили градиентный объект, мы можем определить цвета градиента. Градиент имеет два или более цвета остановки, которые могут быть в любом месте вдоль градиента. Чтобы добавить цвет остановки, необходимо указать его позицию вдоль градиента, она может быть от 0 до 1.

Давайте определим градиент от черного цвета к белому.

my_gradient.addColorStop(0, "black");


my_gradient.addColorStop(1, "white");

Определение градиента не рисует что-либо на холсте, это просто объект, спрятанный где-то в памяти. Чтобы нарисовать градиент, установите fillStyle в градиент и нарисуйте фигуру вроде прямоугольника или линии.



Стиль заполнения градиентом

context.fillStyle = my_gradient;
context.fillRect(0, 0, 300, 225);

И вот результат.



градиент

Предположим, вы хотите градиент сверху вниз. Когда вы создаете градиентный объект, оставьте значения x (первый и третий параметр) постоянными и сделайте значения y (второй и четвертый параметр) в диапазоне от 0 до высоты холста.



Значения x равны 0, значения y меняются

var my_gradient = context.createLinearGradient(0, 0, 0, 225);


my_gradient.addColorStop(0, "black");
my_gradient.addColorStop(1, "white");
context.fillStyle = my_gradient;
context.fillRect(0, 0, 300, 225);

И вот результат.



градиент

Вы также можете сделать градиент по диагонали.



Оба значения x и y меняются

var my_gradient = context.createLinearGradient(0, 0, 300, 225);


my_gradient.addColorStop(0, "black");
my_gradient.addColorStop(1, "white");
context.fillStyle = my_gradient;
context.fillRect(0, 0, 300, 225);

Вот результат.



градиент

Изображения



Поддержка

IE

Firefox

Safari

Chrome

Opera

iPhone

Android

7.0+

3.0+

3.0+

3.0+

10.0+

1.0+

1.0+

* Internet Explorer поддерживает только с библиотекой explorercanvas.

Контекст рисования холста определяет метод drawImage() для вывода изображений. Этот метод может иметь три, пять или девять аргументов.



  • drawImage(image, dx, dy) принимает изображение и выводит его на холст. Заданные координаты (dx, dy) соответствуют левому верхнему углу изображения, координаты (0, 0) выводят изображения в левом верхнем углу холста.

  • drawImage(image, dx, dy, dw, dh) принимает изображение, масштабирует его до ширины dw и высоты dh и выводит в точке с координатами (dx, dy).

  • drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) принимает изображение, обрезает его до прямоугольника (sx, sy, sw, sh), масштабирует до размеров (dw, dh) и выводит в точке с координатами (dx, dy).

Спецификация HTML5 поясняет параметры drawImage():

Исходный прямоугольник это прямоугольник (в пределах исходного изображения), чьи углы это четыре точки (sx, sy), (sx+sw, sy), (sx+sw, sy+sh), (sx, sy+sh).

Прямоугольник назначения это прямоугольник (в холсте), чьи углы в четырех точках (dx, dy), (dx+dw, dy), (dx+dw, dy+dh), (dx, dy+dh).

http://htmlbook.ru/sites/default/files/images/html5/canvas15.png

Чтобы нарисовать изображение на холсте, у вас должно быть изображение. Это может быть существующий элемент  или вы можете создать объект Image() через JavaScript. В любом случае вы должны убедиться, что изображение полностью загружено, прежде чем его можно нарисовать на холсте.

Если вы используете существующий элемент , то можете смело нарисовать его на холсте через событие window.onload.

Использование

id="cat" src="images/cat.png" alt="Спящий кот" width="177" height="113">


Если вы создаете объект полностью на JavaScript, то можете спокойно нарисовать изображение на холсте во время событияImage.onload.



Использование объекта Image()


Необязательные третий и четвертый параметры в методе drawImage() управляют масштабом изображения. То же самое изображение масштабировано до половины его ширины и высоты и повторяется с разными координатами в пределах одного холста.



«многокошечный» эффек

Вот скрипт который производит «многокошечный» эффект.

cat.onload = function() {
for (var x = 0, y = 0;
x < 500 && y < 375;
x += 50, y += 37) {
context.drawImage(cat, x, y, 88, 56);
}
};

Все эти усилия вызывает законный вопрос: почему вы хотите рисовать изображение на холсте в первую очередь? Что дают дополнительные сложности при выводе изображения на холсте по сравнению с элементом  или некоторыми правилами CSS? Даже «многокошечный» эффект может быть сделан с десятью перекрывающимися элементами .

Простой ответ в том, что вы также можете нарисовать текст на холсте. График координат включает текст, линии и формы. Более сложные диаграммы легко могут использовать drawImage() для включения иконок, спрайтов или других графических элементов.

Что насчет IE?



Microsoft Internet Explorer (до версии 8 включительно, текущая версия на момент написания статьи) не поддерживает API Canvas. Тем не менее, Internet Explorer поддерживает фирменную технологию Майкрософт, называемую VML, которая может делать многие из тех же вещей, что и элемент  . Так и родился excanvas.js.

Explorercanvas (excanvas.js) является JavaScript-библиотекой с открытым исходным кодом, которая реализует API Canvas в Internet Explorer. Чтобы ее использовать, включите следующий   в верхнюю часть страницы.









...



Смотрите также:
Давайте порисуем в html5
167.55kb.
Тушинская память
74.93kb.
Сейчас я всё включу, и мы начнём. Вот Вам диктофон
385.16kb.
Я никогда не жаждал ни славы, ни чего-либо подобного
31.5kb.
А давайте-ка, ребята, поиграем в космонавтов!
64.82kb.
Тема: Давайте познакомимся. Обобщение пройденного материала
27.83kb.
Доллар – сатанинский билет?!
56.82kb.
Здравствуйте, выпускники 1963 года!
17.74kb.
Избранный Дао Дао не постоянный
98.69kb.
Основной общеобразовательнай школась
78.88kb.
За окнами просторного кабинета, заклеенными крест-накрест полосками газетной бумаги, уже несколько минут неумолч­но били зенитки
826.11kb.
Давайте зададим себе вопросы: Много ли знают наши дети о природе? Нужно ли им общение с природой? Стремятся ли они наблюдать жизнь природы и оберегать её? Вряд ли
32.76kb.