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

 

Одним из наиболее привлекательных свойств canvas является возможность использовать картинки (изображения). Оно может быть применено для реализации динамических фотокомпозиций, для создания фонов графиков и т.п. Также, это свойство является единственным способом размещения текста на canvas (В спецификации нет ни одной функции для рисования текста). Внешние изображения могут быть любого формата, поддерживаемого Gecko (т.е. форматы PNG, GIF или JPEG). Другие элементы canvas на этой же странице также могут быть использованы как источники изображений.

Импортирование картинок

Обычно импортирование картинок происходит в два этапа:

  • Сначала нам нужна ссылка на объект JavaScript Image или на другой элемент canvas, как источник. Невозможно использовать картинки просто передавая URL/путь до них.
  • Потом мы рисуем картинку на canvas, используя функцию drawImage.

Давайте сначала рассмотрим первый шаг. Доступны четыре варианта:

Использование изображений с текущей страницы

Мы можем получить доступ к любому изображению на странице, используя коллекцию document.images, метод document.getElementsByTagName , либо, если нам известен атрибут ID изображения, метод document.getElementById.

Использование другого элемента canvas

Как и к нормальным изображениям, мы можем получить доступ к элементам canvas через метод document.getElementsByTagName или метод document.getElementById. Перед тем, как вы будете использовать canvas как источник, убедитесь, что вы что-либо уже нарисовали на нём.

Один из наиболее практичных вариантов использования этого метода - создание маленьких превью-картинок для больших изображений canvas.

Создание изображения с нуля

Ещё один вариант - создавать в нашем скрипте новые объекты Image. Главный недостаток такого подхода в том, что если мы не хотим, чтобы наш скрипт "зависал" посередине в ожидании загрузки изображения, нам нужно средство предварительной загрузки изображений.

Чтобы создать новый объект-картинку, мы делаем следующее:

var img = new Image();   // Создаём новый объект Image
img.src = 'myImage.png'; // Устанавливаем путь к источнику

Когда этот скрипт выполняется, изображение начинает загружаться. Если к моменту исполнения инструкции drawImage загрузка ещё не закончилась, скрипт "подвисает" до её окончания. Если вы не хотите, чтобы такое случилось, используйте обработчик события onload:

var img = new Image();   // Создать новый объект Image
img.src = 'myImage.png'; // Установить путь к источнику
img.onload = function(){
  // выполнить drawImage здесь
}

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

Вложение изображения с помощью data: url

Еще один возможный способ вставки изображений - это использование data: url. Data urls позволяют вам полностью определить изображение непосредственно в коде как Base64-кодированную строку. Преимущество данного метода в том, что изображение будет доступно немедленно без каких либо дополнительных запросов к серверу. (Еще одно преимущество заключается в возможности инкапсулировать все Ваши CSS, JavaScript, HTML и изображения в одном файле, что значительно упрощает перемещение всего документа.) Однако изображения, определенные таким способом, не кэшируются, и строковое представление больших изображений может быть довольно длинным.

Рисование изображений

После того как мы указали ссылку на источник мы можем использовать метод drawImage чтобы присвоить изображению положение на холсте. Как мы увидим дальше метод drawImage имеет три вохможных вариацнии. Основная форма метода выглядит таким образом.

drawImage(image, x, y)

Где image это идентификатор изображения а, x и y положение на холсте по оси ординат и абсцис соответственно.

Пример 1 использования изображения

File:ru/Media_Gallery/Canvas_backdrop.pngВ следующем примере мы будем использовать внешнее изображение как фон для небольшого графика. Использование фона позволяет сделать скрипт значительно быстрее. Здесь мы используем только одно изображение поэтому используем событие onload для запуска функции. С помощью метода drawImage мы позиционируем фон на координатах (0,0) тоесть в верхнем левом углу холста

Смотреть этот пример

  function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    var img = new Image();
    img.onload = function(){
      ctx.drawImage(img,0,0);
      ctx.beginPath();
      ctx.moveTo(30,96);
      ctx.lineTo(70,66);
      ctx.lineTo(103,76);
      ctx.lineTo(170,15);
      ctx.stroke();
    }
    img.src = 'images/backdrop.png';
  }

Масштабирование

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

drawImage(image, x, y, width, height)

Где width и height ширина и высота изображения на холсте.

Пример 2 использования изображения

File:en/Media_Gallery/Canvas_scale_image.png В этом примере мы используем одно изображение как обои чтобы повторить его на холсте несколько раз. Это осуществляется с помощью цикла и размещения масштабных изображений на разных позициях. В этом примере первый цикл for отсчитывает ряды а второй цикл for отсчитывает колоны. Изображение равно одной третьей исходного изображения (50x38 пикселей).

Примечание: При масштабировании изображение теряет качество, а текст теряет очертания.

Посмотреть этот пример

  function draw() {
    var ctx = document.getElementById('canvas').getContext('2d');
    var img = new Image();
    img.onload = function(){ 
      for (i=0;i<4;i++){ 
        for (j=0;j<3;j++){ 
          ctx.drawImage(img,j*50,i*38,50,38); 
        } 
      } 
    };
    img.src = 'images/rhino.jpg';
  }

Source image

Разрезание изображений

Третий и последный типа метода drawImage включает 8 новых параметров. Мы будем использовать этот метод чтобы отбражать часть изображения на холсте

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

File:en/Media_Gallery/Canvas_drawimage.jpgПервый параметр image, определяет идентификатор изображения. Следующие 2 элемента определяют положения верхнего левого угла вырезаного изображения относительного исходного положения а, следующие два параметра определяют высоту и ширину вырезаного изображения. Следующие два параметра определяют положение изображения на холсте а, следующие два параметра масштаб изображения.

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

Пример 3 использования изображения

File:en/Media_Gallery/Canvas_drawimage2.jpgВ этом примере мы будем вырезать голову носорога и вставлять ее в рамку с альфа каналом.

В этом примере мы используем другой подход к загрузке изображений, чем в примере выше. Мы просто размечаем изображения непосредственно в HTML документе и используем правила CSS, чтобы скрыть их. Обоим изображениям мы присваиваем атрибут id чтобы их было легче выбрать. Скрипт сам по себе очень прост. Сначала мы вырезаем голову носорого и помещаем ее на холст а, затем помещаем изображение рамки на холст.

Посмотреть этот пример Source image

function draw() {
  var canvas = document.getElementById('canvas');
  var ctx = canvas.getContext('2d');

  // Draw slice
  ctx.drawImage(document.getElementById('source'),
                33,71,104,124,21,20,87,104);

  // Draw frame
  ctx.drawImage(document.getElementById('frame'),0,0);
}

File:ru/Media_Gallery/Canvas_art_gallery.jpgВ финальном примере мы сделаем простую галерею изображений. Галерея состоит из таблицы содержащей несколько изображений. При загрузке страницы каждое изображение вставляется на холст а, затем и рамка вокруг него.

Код ниже, должен говорить сам за себя. Мы используем цикл и добавляем новые элементы на холст. Наверное, единственное, что можно отметить, для тех, кто не очень знаком с DOM, является использование insertBefore метода. insertBefore это метод родительского узла (ячейки таблицы) в который мы хотим вставить наш новый узел (холст).

Посмотреть этот пример

function draw() {

  // Loop through all images
  for (i=0;i<document.images.length;i++){

    // Don't add a canvas for the frame image
    if (document.images[i].getAttribute('id')!='frame'){

      // Create canvas element
      canvas = document.createElement('CANVAS');
      canvas.setAttribute('width',132);
      canvas.setAttribute('height',150);

      // Insert before the image
      document.images[i].parentNode.insertBefore(canvas,document.images[i]);

      ctx = canvas.getContext('2d');

      // Draw image to canvas
      ctx.drawImage(document.images[i],15,20);

      // Add frame
      ctx.drawImage(document.getElementById('frame'),0,0);
    }
  }
}

Метки документа и участники

Метки: 
Contributors to this page: pinal, teoli, RAP1D, oktoberliner, KeRNel x86, Chernetsky
Обновлялась последний раз: pinal,