Введение в HTML5

Холст HTML5 – основы

Разбить на страницы
Показывать лекцию целиком

Михаил Сучан · 8 января 2009 г.

Введение

Спецификация HTML5 (http://www.whatwg.org/specs/web-apps/current-work/multipage/) включает множество новых свойств, одним из которых является элемент canvas (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html). Холст ( canvas ) HTML5 предоставляет простой и мощный способ создания графических изображений с помощью JavaScript. Для каждого элемента canvas можно использовать "контекст" (представьте страницу в альбоме для рисования), в который можно выполнять команды JavaScript для рисования. Браузеры могут реализовать несколько контекстов холстов и различные API предоставляют функции для рисования.

Большинство основных браузеров включают возможности контекста холста 2D - Opera, Firefox, Konqueror и Safari. Кроме того существуют экспериментальные сборки браузера Opera, которые включают поддержку контекста холста 3D, и дополнение, которое обеспечивает поддержку холста 3D в Firefox:

  • Ссылка для загрузки сборки Opera с поддержкой холста 3D, HTML видео и в/в файлов (http://labs.opera.com/news/2008/11/25/).
  • Узнайте больше об использовании контекста холста 3D в Opera (http://my.opera.com/timjoh/blog/2007/11/13/taking-the-canvas-to-another-dimension).
  • Узнайте больше о получении и использовании контекста холста 3D в Firefox (http://blog.vlad1.com/2007/11/26/canvas-3d-gl-power-web-style/).
  • В данной статье рассматриваются основы реализации контекста холста 2D и использования основных функций холста, включая линии, примитивы форм, изображения, текст и другие. Предполагается, что вы уже знакомы с основами JavaScript.

    Отметим, что код всех примеров можно загрузить одним файлом zip-архива (http://dev.opera.com/articles/view/html-5-canvas-the-basics/canvas-primer.zip), а также просмотреть их в действии, используя ссылки ниже.

    Основы использования холста

    Создание контекста холста на странице состоит просто в добавлении элемента <canvas> в документ HTML следующим образом:

    <canvas id="myCanvas" width="200" height="150">
    "Резервный контент на случай отсутствия поддержки 
    холста в браузере."
    <span style="display:block;width:150px;height:100px;background:#00f"> </span>
    </canvas>

    Необходимо определить ID элемента, чтобы можно было найти элемент позже в коде JavaScript, и нужно также определить ширину и высоту холста.

    Мы создали альбом для рисования, так что теперь давайте коснемся пером бумаги. Чтобы рисовать на холсте, нужно использовать JavaScript. Сначала мы находим элемент холста с помощью getElementById, затем инициализируем требуемый контекст. После этого можно начинать рисовать на холсте с помощью доступных в API контекста команд. Следующий сценарий (попробуйте выполнить пример - http://www.robodesign.ro/coding/canvas-primer/20081208/example-using-canvas.html) рисует простой прямоугольник на определенном выше холсте:

    window.addEventListener('load', function () {
      // Получаем ссылку на элемент.
      var elem = document.getElementById('myCanvas');
      if (!elem || !elem.getContext) {
        return;
      }
    
      // Получаем контекст 2d.
      var context = elem.getContext('2d');
      if (!context) {
        return;
      }
    
      // Все сделано! Теперь можно нарисовать синий прямоугольник.
      context.fillStyle = '#00f';
      context.fillRect(0, 0, 150, 100);
    }, false);
    

    Можно включить этот сценарий в заголовок документа или во внешний файл - все определяется вашими предпочтениями.

    API контекста 2D

    Теперь, когда мы создали свое первое базовое изображение на холсте, давайте посмотрим немного глубже на API холста 2D, и посмотрим, что нам доступно для использования.

    Основные линии и штрихи

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

    С помощью свойств fillStyle и strokeStyle можно легко задать цвета, используемые для изображения заполненных фигур и штрихов. Значения цветов, которые можно использовать, такие же как и в CSS: шестнадцатеричные коды, rgb(), rgba() и даже hsla(), если браузер поддерживает это (например, это свойство поддерживается в Opera 10.00 и более поздних версиях).

    С помощью fillRect можно рисовать заполненные прямоугольники. С помощью strokeRect можно рисовать прямоугольники, используя только границы, без заполнения. Если вы хотите очистить некоторую часть холста, можно использовать clearRect. Эти три метода используют одинаковые аргументы: x, y, width, height. Два первых аргумента сообщают координаты (x,y), а два последних аргумента задают ширину и высоту прямоугольника.

    Чтобы изменить толщину линий, можно использовать свойство lineWidth. Давайте посмотрим на пример, который использует fillRect, strokeRect, clearRect и другие возможности:

    context.fillStyle = '#00f'; // синий 
    context.strokeStyle = '#f00'; // красный 
    context.lineWidth = 4;
    
    // Рисуем несколько прямоугольников.
    context.fillRect (0, 0, 150, 50);
    context.strokeRect(0, 60, 150, 50);
    context.clearRect (30, 25, 90, 60);
    context.strokeRect(30, 25, 90, 60);

    Этот пример создает вывод, который можно видеть на рисунке 6.1.

    (рис 6.1) Пример использования fillRect, strokeRect и clearRect

    Пути

    Пути холста позволяют рисовать произвольные фигуры. Вы чертите сначала "контур", затем выбираете для рисования штрих и в конце заполняете при желании фигуру. Создание специальной фигуры выполняется легко – чтобы начать рисовать путь, используйте beginPath(), затем начертите путь, который формирует фигуру с помощью прямых линий, кривых и других примитивов. Когда закончите, вызовите fill и stroke, если хотите заполнить фигуру или нарисовать штрихи, затем вызовите closePath(), чтобы закончить рисование фигуры.

    Следующий пример показывает рисование треугольника:

    // Задаем свойства стиля оформления.
    context.fillStyle = '#00f';
    context.strokeStyle = '#f00';
    context.lineWidth = 4;
    
    context.beginPath();
    // Начинаем с верхней левой точки.
    context.moveTo(10, 10); // задаем координаты (x,y) 
    context.lineTo(100, 10);
    context.lineTo(10, 100);
    context.lineTo(10, 10);
    
    // Готово! Теперь заполните фигуру, и начертите штрихи.
    // Примечание: фигура будет невидимой, пока не будет вызван 
    // любой из этих трех методов.
    context.fill();
    context.stroke();
    context.closePath();

    Это порождает вызов, показанный на рисунке 6.2.

    (рис 6.2) Простой треугольник

    Я приготовил также пример более сложных путей, использующих прямые линии, кривые, и дуги (http://www.robodesign.ro/coding/canvas-primer/20081208/example-paths.html) – можно его посмотреть.

    Вставка изображений

    Метод drawImage позволяет вставлять другие изображения (элементы img и canvas ) в контекст холста. В браузере Opera можно также рисовать изображения SVG внутри холста. Это достаточно сложный метод, который получает три, пять или девять аргументов:

  • Три аргумента: Базовый вариант drawImage использует один аргумент для указания на включаемое изображение, и два для определения координат места назначения внутри контекста холста.
  • Пять аргументов: Второй вариант использования drawImage включает приведенные выше три аргумента, плюс два для определения ширины и высоты вставляемого изображения (если вы захотите изменить его размер).
  • Девять аргументов: Самый развитый вариант использования drawImage включает кроме пяти аргументов два значения для координат внутри исходного изображения, и два значения для ширины и высоты внутри исходного изображения. Эти значения позволяют динамически обрезать исходное изображение перед вставкой в контекст холста.
  • Следующий пример кода показывает все три типа drawImage в действии (http://www.robodesign.ro/coding/canvas-primer/20081208/example-drawimage.html):

    // Три аргумента: элемент, координаты места назначения (x,y).
    
    context.drawImage(img_elem, dx, dy);
    
    // Пять аргументов: элемент, координаты места назначения (x,y) 
    // и ширина и высота места назначения (если вы хотите изменить // размер исходного изображения).
    
    context.drawImage(img_elem, dx, dy, dw, dh);
    
    // Девять аргументов: координаты места назначения (x,y), 
    // ширина и высота источника (для обрезки), 
    // координаты места назначения (x,y), 
    // ширина и высота места назначения (изменение размера).
    
    context.drawImage(img_elem, sx, sy, sw, sh, dx, dy, dw, dh);

    Это должно выводиться, как показано на рисунке 6.3.

    (рис 6.3) Пример использования drawImage

    Манипуляции с пикселями

    API контекста 2D предоставляет три метода, которые помогают рисовать с точностью до пикселя: createImageData, getImageData, и putImageData.

    Пиксели хранятся в объектах типа ImageData. Каждый объект имеет три свойства: width, height и data. Свойство data имеет тип CanvasPixelArray, имеющий количество элементов равное width*height*4 ; это означает, что для каждого пикселя определяются значения красного, зеленого, синего цветов и alpha, в том порядке, в котором они должны появиться (все значения находятся в диапазоне от 0 до 255, включая alpha!). Пиксели упорядочиваются слева направо, ряд за рядом, сверху вниз.

    Чтобы лучше понять, как все это работает, рассмотрим пример, который рисует блок красных пикселей (http://www.robodesign.ro/coding/canvas-primer/20081208/example-imagedata2.html).

    // Создаем объект ImageData
    
    var imgd = context.createImageData(50,50);
    var pix = imgd.data;
    
    // Цикл по всем пикселям и задание прозрачного красного цвета
    
    for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i ] = 255; // канал red (красный)
    pix[i+3] = 127; // канал alpha 
    }
    
    // Отображение объекта ImageData в заданных координатах (x,y).
    
    context.putImageData(imgd, 0,0);

    Примечание: Не все браузеры реализуют createImageData. В таких браузерах необходимо получить объект ImageData с помощью метода getImageData. Посмотрите пример кода по следующей ссылке (http://www.robodesign.ro/coding/canvas-primer/20081208/example-imagedata2.html).

    С помощью возможностей ImageData можно делать значительно больше, чем только это. Например, можно выполнить фильтрацию изображения, или можно сделать математическую визуализацию (представьте фракталы или что-то еще). Следующий код показывает, как создать простой фильтр для инверсии цвета (http://www.robodesign.ro/coding/canvas-primer/20081208/example-imagedata.html):

    // Получаем CanvasPixelArray из заданных координат 
    // и размеров.
    
    var imgd = context.getImageData(x, y, width, height);
    var pix = imgd.data;
    
    // Цикл по всем пикселям для инверсии цвета.
    
    for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i ] = 255 - pix[i ]; // red
    pix[i+1] = 255 - pix[i+1]; // green
    pix[i+2] = 255 - pix[i+2]; // blue
    // i+3 будет alpha (четвертый элемент)
    }
    
    // Выводим ImageData в заданных координатах (x,y).
    context.putImageData(imgd, x, y);

    Рисунок 6.4 показывает фильтр инверсии цвета, примененный к графическому изображению Opera (сравните с рисунком 6.3, который показывает исходную цветовую схему графического изображения Opera).

    (рис 6.4) Фильтр инверсии цвета в действии

    Текст

    API текста доступен только в недавних сборках WebKit, и в ночных сборках Firefox 3.1, но я решил включить его здесь для полноты изложения.

    На объекте context имеются следующие свойства текста:

  • font: Определяет шрифт текста, таким же образом как свойство CSS font-family )
  • textAlign: Определяет горизонтальное выравнивание текста. Значения: start, end, left, right, center. Значение по умолчанию: start.
  • textBaseline: Определяет вертикальное выравнивание текста. Значения: top, hanging, middle, alphabetic, ideographic, bottom. Значение по умолчанию: alphabetic.
  • Для отображения текста имеется два метода: fillText и strokeText.

    Первый из них изображает форму текста, заполненную с помощью текущего стиля fillStyle, в то время как второй изображает контур/границу текста используя текущий стиль strokeStyle. Оба получают три аргумента: текст для вывода, и координаты (x,y), определяющие место отображения. Существует также необязательный четвертый аргумент – максимальная ширина. Это приводит к тому, что браузер, если понадобится, сжимает текст, чтобы разместить его внутри заданной ширины.

    Свойства выравнивания текста влияют на положение текста относительно координат (x,y), заданных в методах отображения.

    Теперь пора обратиться к практике – следующий код является примером создания на холсте простого текста "hello world".

    context.fillStyle = '#00f';
    context.font = 'italic 30px sans-serif';
    context.textBaseline = 'top';
    context.fillText ('Hello world!', 0, 0);
    context.font = 'bold 30px sans-serif';
    context.strokeText('Hello world!', 0, 50);

    Рисунок 6.5 показывает вывод этого примера.

    (рис 6.5) Отображение простого текста на холсте

    Тени

    API теней предоставляет четыре свойства:

  • shadowColor: Задает желательный цвет тени. Допустимые значения такие же как и значения цвета в CSS.
  • shadowBlur: Задает величину размытости на тени в пикселях. Чем меньше значение размытости, тем более резкой будет тень. Создает эффект очень похожий на размытость по Гауссу в Photoshop.
  • shadowOffsetX и shadowOffsetY: Определяет смещение тени по x и y в пикселях.
  • Использование вполне очевидно, как показано в следующем примере кода тени холста (http://www.robodesign.ro/coding/canvas-primer/20081208/example-shadows.html):

    context.shadowOffsetX = 5;
    context.shadowOffsetY = 5;
    context.shadowBlur = 4;
    context.shadowColor = 'rgba(255, 0, 0, 0.5)';
    context.fillStyle = '#00f';
    context.fillRect(20, 20, 150, 100);

    Этот код отображается, как показано на рисунке 6.6.

    (рис 6.6) Пример тени холста – синий прямоугольник с красной тенью

    Градиенты

    Свойства fillStyle и strokeStyle могут также иметь присвоенные им объекты CanvasGradient вместо строк цвета CSS – это позволяет использовать цветовые градиенты для окрашивания линий и заполнений вместо однородных цветов.

    Для создания объектов CanvasGradient можно использовать два метода: createLinearGradient и createRadialGradient. Первый из них создает линейный градиент – линии цвета все идут в одном направлении – в то время как второй создает радиальный градиент – цветовые окружности, расходящиеся из одной точки.

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

    Следующий код показывает, как использовать градиенты:

    // Необходимо предоставить для градиента 
    // координаты (x,y) источника и места назначения 
    // (откуда он начинается и где заканчивается).
    
    var gradient1 = context.createLinearGradient(sx, sy, dx, dy);
    
    // Теперь можно добавить в градиент цвета.
    // Первый аргумент задает позицию цвета в градиенте. 
    // Диапазон допустимых значений от 0 (начало градиента) 
    // до 1 (конец градиента).
    // Второй аргумент сообщает требуемый цвет, 
    // используя формат цвета CSS.
    
    gradient1.addColorStop(0, '#f00'); // красный 
    gradient1.addColorStop(0.5, '#ff0'); // желтый 
    gradient1.addColorStop(1, '#00f'); // синий 
    
    // Для радиального градиента также нужно задать 
    // источник и радиус окружности назначения.
    // Координаты (x,y) определяют центр окружности 
    // (начало и окружности назначения).
    
    var gradient2 = context.createRadialGradient(sx, sy, sr, dx, dy, dr);
    
    // Добавление цветов для радиального градиента делается 
    // как добавление цветов к линейным градиентам.

    Я подготовил также более сложный пример, который использует линейный градиент, тени и текст ( http://www.robodesign.ro/coding/canvas-primer/20081208/example-gradients.html). Пример создает вывод, показанный на рисунке 6.7.

    (рис 6.7) Пример с использованием линейного градиента

    Сетевые примеры использования холста

    Если вы хотите узнать, что другие сделали с помощью холста, то можно посмотреть следующие проекты:

  • Виджеты Opera:
  • SimAquarium (http://widgets.opera.com/widget/5040/)
  • Artist's Sketchbook (http://widgets.opera.com/widget/4647/)
  • Spirograph (http://widgets.opera.com/widget/5218/)
  • Сетевые проекты и демонстрации
  • Полином Ньютона (http://www.benjoffe.com/code/demos/interpolate/)
  • Canvascape - "3D Walker" (http://www.benjoffe.com/code/demos/canvascape/)
  • Paint.Web – демонстрация рисования, открытый исходный код (http://code.google.com/p/paintweb)
  • Полет среди звезд (http://arapehlivanian.com/wp-content/uploads/2007/02/canvas.html)
  • Интерактивный blob (http://www.blobsallad.se/)
  • Заключение

    Холст является одним из наиболее интересных свойств HTML5, и он готов к использованию в большинстве современных браузеров. Он предоставляет все необходимое для создания игр, усовершенствований интерфейса пользователя, а также других вещей. API контекста 2D включает множество функций помимо рассмотренных в этой статье. Я надеюсь, что вы получили хорошее представление о возможностях холста и жажду узнать больше.

    Страницы:

    Михаил Сучан · 8 января 2009 г.

    Введение

    Спецификация HTML5 (http://www.whatwg.org/specs/web-apps/current-work/multipage/) включает множество новых свойств, одним из которых является элемент canvas (http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html). Холст ( canvas ) HTML5 предоставляет простой и мощный способ создания графических изображений с помощью JavaScript. Для каждого элемента canvas можно использовать "контекст" (представьте страницу в альбоме для рисования), в который можно выполнять команды JavaScript для рисования. Браузеры могут реализовать несколько контекстов холстов и различные API предоставляют функции для рисования.

    Большинство основных браузеров включают возможности контекста холста 2D - Opera, Firefox, Konqueror и Safari. Кроме того существуют экспериментальные сборки браузера Opera, которые включают поддержку контекста холста 3D, и дополнение, которое обеспечивает поддержку холста 3D в Firefox:

  • Ссылка для загрузки сборки Opera с поддержкой холста 3D, HTML видео и в/в файлов (http://labs.opera.com/news/2008/11/25/).
  • Узнайте больше об использовании контекста холста 3D в Opera (http://my.opera.com/timjoh/blog/2007/11/13/taking-the-canvas-to-another-dimension).
  • Узнайте больше о получении и использовании контекста холста 3D в Firefox (http://blog.vlad1.com/2007/11/26/canvas-3d-gl-power-web-style/).
  • В данной статье рассматриваются основы реализации контекста холста 2D и использования основных функций холста, включая линии, примитивы форм, изображения, текст и другие. Предполагается, что вы уже знакомы с основами JavaScript.

    Отметим, что код всех примеров можно загрузить одним файлом zip-архива (http://dev.opera.com/articles/view/html-5-canvas-the-basics/canvas-primer.zip), а также просмотреть их в действии, используя ссылки ниже.

    Основы использования холста

    Создание контекста холста на странице состоит просто в добавлении элемента <canvas> в документ HTML следующим образом:

    <canvas id="myCanvas" width="200" height="150">
    "Резервный контент на случай отсутствия поддержки 
    холста в браузере."
    <span style="display:block;width:150px;height:100px;background:#00f"> </span>
    </canvas>

    Необходимо определить ID элемента, чтобы можно было найти элемент позже в коде JavaScript, и нужно также определить ширину и высоту холста.

    Мы создали альбом для рисования, так что теперь давайте коснемся пером бумаги. Чтобы рисовать на холсте, нужно использовать JavaScript. Сначала мы находим элемент холста с помощью getElementById, затем инициализируем требуемый контекст. После этого можно начинать рисовать на холсте с помощью доступных в API контекста команд. Следующий сценарий (попробуйте выполнить пример - http://www.robodesign.ro/coding/canvas-primer/20081208/example-using-canvas.html) рисует простой прямоугольник на определенном выше холсте:

    window.addEventListener('load', function () {
      // Получаем ссылку на элемент.
      var elem = document.getElementById('myCanvas');
      if (!elem || !elem.getContext) {
        return;
      }
    
      // Получаем контекст 2d.
      var context = elem.getContext('2d');
      if (!context) {
        return;
      }
    
      // Все сделано! Теперь можно нарисовать синий прямоугольник.
      context.fillStyle = '#00f';
      context.fillRect(0, 0, 150, 100);
    }, false);
    

    Можно включить этот сценарий в заголовок документа или во внешний файл - все определяется вашими предпочтениями.

    API контекста 2D

    Теперь, когда мы создали свое первое базовое изображение на холсте, давайте посмотрим немного глубже на API холста 2D, и посмотрим, что нам доступно для использования.

    Основные линии и штрихи

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

    С помощью свойств fillStyle и strokeStyle можно легко задать цвета, используемые для изображения заполненных фигур и штрихов. Значения цветов, которые можно использовать, такие же как и в CSS: шестнадцатеричные коды, rgb(), rgba() и даже hsla(), если браузер поддерживает это (например, это свойство поддерживается в Opera 10.00 и более поздних версиях).

    С помощью fillRect можно рисовать заполненные прямоугольники. С помощью strokeRect можно рисовать прямоугольники, используя только границы, без заполнения. Если вы хотите очистить некоторую часть холста, можно использовать clearRect. Эти три метода используют одинаковые аргументы: x, y, width, height. Два первых аргумента сообщают координаты (x,y), а два последних аргумента задают ширину и высоту прямоугольника.

    Чтобы изменить толщину линий, можно использовать свойство lineWidth. Давайте посмотрим на пример, который использует fillRect, strokeRect, clearRect и другие возможности:

    context.fillStyle = '#00f'; // синий 
    context.strokeStyle = '#f00'; // красный 
    context.lineWidth = 4;
    
    // Рисуем несколько прямоугольников.
    context.fillRect (0, 0, 150, 50);
    context.strokeRect(0, 60, 150, 50);
    context.clearRect (30, 25, 90, 60);
    context.strokeRect(30, 25, 90, 60);

    Этот пример создает вывод, который можно видеть на рисунке 6.1.

    (рис 6.1) Пример использования fillRect, strokeRect и clearRect

    Пути

    Пути холста позволяют рисовать произвольные фигуры. Вы чертите сначала "контур", затем выбираете для рисования штрих и в конце заполняете при желании фигуру. Создание специальной фигуры выполняется легко – чтобы начать рисовать путь, используйте beginPath(), затем начертите путь, который формирует фигуру с помощью прямых линий, кривых и других примитивов. Когда закончите, вызовите fill и stroke, если хотите заполнить фигуру или нарисовать штрихи, затем вызовите closePath(), чтобы закончить рисование фигуры.

    Следующий пример показывает рисование треугольника:

    // Задаем свойства стиля оформления.
    context.fillStyle = '#00f';
    context.strokeStyle = '#f00';
    context.lineWidth = 4;
    
    context.beginPath();
    // Начинаем с верхней левой точки.
    context.moveTo(10, 10); // задаем координаты (x,y) 
    context.lineTo(100, 10);
    context.lineTo(10, 100);
    context.lineTo(10, 10);
    
    // Готово! Теперь заполните фигуру, и начертите штрихи.
    // Примечание: фигура будет невидимой, пока не будет вызван 
    // любой из этих трех методов.
    context.fill();
    context.stroke();
    context.closePath();

    Это порождает вызов, показанный на рисунке 6.2.

    (рис 6.2) Простой треугольник

    Я приготовил также пример более сложных путей, использующих прямые линии, кривые, и дуги (http://www.robodesign.ro/coding/canvas-primer/20081208/example-paths.html) – можно его посмотреть.

    Вставка изображений

    Метод drawImage позволяет вставлять другие изображения (элементы img и canvas ) в контекст холста. В браузере Opera можно также рисовать изображения SVG внутри холста. Это достаточно сложный метод, который получает три, пять или девять аргументов:

  • Три аргумента: Базовый вариант drawImage использует один аргумент для указания на включаемое изображение, и два для определения координат места назначения внутри контекста холста.
  • Пять аргументов: Второй вариант использования drawImage включает приведенные выше три аргумента, плюс два для определения ширины и высоты вставляемого изображения (если вы захотите изменить его размер).
  • Девять аргументов: Самый развитый вариант использования drawImage включает кроме пяти аргументов два значения для координат внутри исходного изображения, и два значения для ширины и высоты внутри исходного изображения. Эти значения позволяют динамически обрезать исходное изображение перед вставкой в контекст холста.
  • Следующий пример кода показывает все три типа drawImage в действии (http://www.robodesign.ro/coding/canvas-primer/20081208/example-drawimage.html):

    // Три аргумента: элемент, координаты места назначения (x,y).
    
    context.drawImage(img_elem, dx, dy);
    
    // Пять аргументов: элемент, координаты места назначения (x,y) 
    // и ширина и высота места назначения (если вы хотите изменить // размер исходного изображения).
    
    context.drawImage(img_elem, dx, dy, dw, dh);
    
    // Девять аргументов: координаты места назначения (x,y), 
    // ширина и высота источника (для обрезки), 
    // координаты места назначения (x,y), 
    // ширина и высота места назначения (изменение размера).
    
    context.drawImage(img_elem, sx, sy, sw, sh, dx, dy, dw, dh);

    Это должно выводиться, как показано на рисунке 6.3.

    (рис 6.3) Пример использования drawImage

    Манипуляции с пикселями

    API контекста 2D предоставляет три метода, которые помогают рисовать с точностью до пикселя: createImageData, getImageData, и putImageData.

    Пиксели хранятся в объектах типа ImageData. Каждый объект имеет три свойства: width, height и data. Свойство data имеет тип CanvasPixelArray, имеющий количество элементов равное width*height*4 ; это означает, что для каждого пикселя определяются значения красного, зеленого, синего цветов и alpha, в том порядке, в котором они должны появиться (все значения находятся в диапазоне от 0 до 255, включая alpha!). Пиксели упорядочиваются слева направо, ряд за рядом, сверху вниз.

    Чтобы лучше понять, как все это работает, рассмотрим пример, который рисует блок красных пикселей (http://www.robodesign.ro/coding/canvas-primer/20081208/example-imagedata2.html).

    // Создаем объект ImageData
    
    var imgd = context.createImageData(50,50);
    var pix = imgd.data;
    
    // Цикл по всем пикселям и задание прозрачного красного цвета
    
    for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i ] = 255; // канал red (красный)
    pix[i+3] = 127; // канал alpha 
    }
    
    // Отображение объекта ImageData в заданных координатах (x,y).
    
    context.putImageData(imgd, 0,0);

    Примечание: Не все браузеры реализуют createImageData. В таких браузерах необходимо получить объект ImageData с помощью метода getImageData. Посмотрите пример кода по следующей ссылке (http://www.robodesign.ro/coding/canvas-primer/20081208/example-imagedata2.html).

    С помощью возможностей ImageData можно делать значительно больше, чем только это. Например, можно выполнить фильтрацию изображения, или можно сделать математическую визуализацию (представьте фракталы или что-то еще). Следующий код показывает, как создать простой фильтр для инверсии цвета (http://www.robodesign.ro/coding/canvas-primer/20081208/example-imagedata.html):

    // Получаем CanvasPixelArray из заданных координат 
    // и размеров.
    
    var imgd = context.getImageData(x, y, width, height);
    var pix = imgd.data;
    
    // Цикл по всем пикселям для инверсии цвета.
    
    for (var i = 0, n = pix.length; i < n; i += 4) {
    pix[i ] = 255 - pix[i ]; // red
    pix[i+1] = 255 - pix[i+1]; // green
    pix[i+2] = 255 - pix[i+2]; // blue
    // i+3 будет alpha (четвертый элемент)
    }
    
    // Выводим ImageData в заданных координатах (x,y).
    context.putImageData(imgd, x, y);

    Рисунок 6.4 показывает фильтр инверсии цвета, примененный к графическому изображению Opera (сравните с рисунком 6.3, который показывает исходную цветовую схему графического изображения Opera).

    (рис 6.4) Фильтр инверсии цвета в действии

    Текст

    API текста доступен только в недавних сборках WebKit, и в ночных сборках Firefox 3.1, но я решил включить его здесь для полноты изложения.

    На объекте context имеются следующие свойства текста:

  • font: Определяет шрифт текста, таким же образом как свойство CSS font-family )
  • textAlign: Определяет горизонтальное выравнивание текста. Значения: start, end, left, right, center. Значение по умолчанию: start.
  • textBaseline: Определяет вертикальное выравнивание текста. Значения: top, hanging, middle, alphabetic, ideographic, bottom. Значение по умолчанию: alphabetic.
  • Для отображения текста имеется два метода: fillText и strokeText.

    Первый из них изображает форму текста, заполненную с помощью текущего стиля fillStyle, в то время как второй изображает контур/границу текста используя текущий стиль strokeStyle. Оба получают три аргумента: текст для вывода, и координаты (x,y), определяющие место отображения. Существует также необязательный четвертый аргумент – максимальная ширина. Это приводит к тому, что браузер, если понадобится, сжимает текст, чтобы разместить его внутри заданной ширины.

    Свойства выравнивания текста влияют на положение текста относительно координат (x,y), заданных в методах отображения.

    Теперь пора обратиться к практике – следующий код является примером создания на холсте простого текста "hello world".

    context.fillStyle = '#00f';
    context.font = 'italic 30px sans-serif';
    context.textBaseline = 'top';
    context.fillText ('Hello world!', 0, 0);
    context.font = 'bold 30px sans-serif';
    context.strokeText('Hello world!', 0, 50);

    Рисунок 6.5 показывает вывод этого примера.

    (рис 6.5) Отображение простого текста на холсте

    Тени

    API теней предоставляет четыре свойства:

  • shadowColor: Задает желательный цвет тени. Допустимые значения такие же как и значения цвета в CSS.
  • shadowBlur: Задает величину размытости на тени в пикселях. Чем меньше значение размытости, тем более резкой будет тень. Создает эффект очень похожий на размытость по Гауссу в Photoshop.
  • shadowOffsetX и shadowOffsetY: Определяет смещение тени по x и y в пикселях.
  • Использование вполне очевидно, как показано в следующем примере кода тени холста (http://www.robodesign.ro/coding/canvas-primer/20081208/example-shadows.html):

    context.shadowOffsetX = 5;
    context.shadowOffsetY = 5;
    context.shadowBlur = 4;
    context.shadowColor = 'rgba(255, 0, 0, 0.5)';
    context.fillStyle = '#00f';
    context.fillRect(20, 20, 150, 100);

    Этот код отображается, как показано на рисунке 6.6.

    (рис 6.6) Пример тени холста – синий прямоугольник с красной тенью

    Градиенты

    Свойства fillStyle и strokeStyle могут также иметь присвоенные им объекты CanvasGradient вместо строк цвета CSS – это позволяет использовать цветовые градиенты для окрашивания линий и заполнений вместо однородных цветов.

    Для создания объектов CanvasGradient можно использовать два метода: createLinearGradient и createRadialGradient. Первый из них создает линейный градиент – линии цвета все идут в одном направлении – в то время как второй создает радиальный градиент – цветовые окружности, расходящиеся из одной точки.

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

    Следующий код показывает, как использовать градиенты:

    // Необходимо предоставить для градиента 
    // координаты (x,y) источника и места назначения 
    // (откуда он начинается и где заканчивается).
    
    var gradient1 = context.createLinearGradient(sx, sy, dx, dy);
    
    // Теперь можно добавить в градиент цвета.
    // Первый аргумент задает позицию цвета в градиенте. 
    // Диапазон допустимых значений от 0 (начало градиента) 
    // до 1 (конец градиента).
    // Второй аргумент сообщает требуемый цвет, 
    // используя формат цвета CSS.
    
    gradient1.addColorStop(0, '#f00'); // красный 
    gradient1.addColorStop(0.5, '#ff0'); // желтый 
    gradient1.addColorStop(1, '#00f'); // синий 
    
    // Для радиального градиента также нужно задать 
    // источник и радиус окружности назначения.
    // Координаты (x,y) определяют центр окружности 
    // (начало и окружности назначения).
    
    var gradient2 = context.createRadialGradient(sx, sy, sr, dx, dy, dr);
    
    // Добавление цветов для радиального градиента делается 
    // как добавление цветов к линейным градиентам.

    Я подготовил также более сложный пример, который использует линейный градиент, тени и текст ( http://www.robodesign.ro/coding/canvas-primer/20081208/example-gradients.html). Пример создает вывод, показанный на рисунке 6.7.

    (рис 6.7) Пример с использованием линейного градиента

    Сетевые примеры использования холста

    Если вы хотите узнать, что другие сделали с помощью холста, то можно посмотреть следующие проекты:

  • Виджеты Opera:
  • SimAquarium (http://widgets.opera.com/widget/5040/)
  • Artist's Sketchbook (http://widgets.opera.com/widget/4647/)
  • Spirograph (http://widgets.opera.com/widget/5218/)
  • Сетевые проекты и демонстрации
  • Полином Ньютона (http://www.benjoffe.com/code/demos/interpolate/)
  • Canvascape - "3D Walker" (http://www.benjoffe.com/code/demos/canvascape/)
  • Paint.Web – демонстрация рисования, открытый исходный код (http://code.google.com/p/paintweb)
  • Полет среди звезд (http://arapehlivanian.com/wp-content/uploads/2007/02/canvas.html)
  • Интерактивный blob (http://www.blobsallad.se/)
  • Заключение

    Холст является одним из наиболее интересных свойств HTML5, и он готов к использованию в большинстве современных браузеров. Он предоставляет все необходимое для создания игр, усовершенствований интерфейса пользователя, а также других вещей. API контекста 2D включает множество функций помимо рассмотренных в этой статье. Я надеюсь, что вы получили хорошее представление о возможностях холста и жажду узнать больше.

    Вернуться к учебному плану