Одна из самых впечатляющих функций <canvas>
- это возможность использования изображений. Вы можете использовать <canvas>
для динамического изменения таких фото, как фоны, графики, для спрайтов в играх, и так далее. При этом в качестве изображений можно брать любые форматы: PNG, GIF, JPEG.
Метод drawImage()
Для рисования изображения на canvas
используется метод drawImage()
. Его синтаксис может быть таким:
1 2 3 | drawImage(image, dx, dy) drawImage(image, dx, dy, dWidth, dHeight) drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) |
где:
image
- это элемент для отображения в контексте. Функция принимает любой источник изображения, пригодный для отображения на холсте.dx
- координата по оси Х, обозначающая стартовую точку холста-приёмника, в которую будет помещён верхний левый угол исходногоimage
.dy
- координата по оси Y, обозначающая стартовую точку холста-приёмника, в которую будет помещён верхний левый угол исходногоimage
.dWidth
- ширина изображения, полученного из исходногоimage
. Эта опция позволяет масштабировать изображение по ширине. Если опция не задана, изображение не будет масштабировано.dHeight
- высота изображения, полученного из исходногоimage
. Эта опция позволяет масштабировать изображение по высоте. Если опция не задана, изображение не будет масштабировано.
sx
- координата по оси X верхнего левого угла фрагмента, который будет вырезан из изображения-источника и помещён в контекст-приёмник.sy
- координата по оси Y верхнего левого угла фрагмента, который будет вырезан из изображения-источника и помещён в контекст-приёмник.sWidth
- ширина фрагмента, который будет вырезан из изображения источника и помещён в контекст-приёмник. Если не задана, фрагмент от точки, заданнойsx
иsy
до правого нижнего угла источника будет целиком скопирован в контекст-приёмник.sHeight
- высота фрагмента, который будет вырезан из изображения источника и помещён в контекст-приёмник.
Если нам нужно нарисовать картинку в canvas
частично, нужно указывать сначала координаты левого верхнего угла картинки-исходника и нужные размеры по ширине и высоте, а затем уже координаты расположения верхнего левого угла этой картинки в canvas
, а также размеры в canvas
по ширине и высоте. Учтите, если размеры не будут совпадать, то картинка в canvas
будет отображаться с искажениями.
Примечание: Метод drawImage()
использует внутренние размеры элемента-источника, выраженные в CSS-пикселях (а не реальные размеры самой картинки).
На примере ниже вы можете посмотреть несколько вариантов рисования с помощью функции drawImage()
:
See the Pen canvas drawImage() options by Elen (@ambassador) on CodePen.
В коде выше в функциях при клике на кнопке в качестве исходного изображения мы использовали то, что находилось ниже элемента canvas
и имело id="pic".
Есть несколько способов, чтобы получить изображения для использования на холсте.
Использование изображений из той же страницы
Мы можем получить ссылку на изображение, на той же странице, на canvas с используя один из способов:
- коллекция
document.images
(например,document.images[0]
); - метод
document.getElementsByTagName()
(например,document.getElementsByTagName('img')[0]
) ; - чтобы получить конкретное изображение по
id
, вы можете использоватьdocument.getElementById()
, - загруженное пользователем изображение.
Первый и третий способ мы уже использовали. Если нам нужно загрузить изображение, нужно понимать, что его загрузка может занять время, поэтому нужно обрабатывать для изображения событие onload
, и в нем получать размеры изображения.
В коде ниже вы найдете такой способ. При клике на кнопку вы будете загружать увеличенное изображение и отображать его в canvas
.
See the Pen drawImage in canvas by Elen (@ambassador) on CodePen.
Если при этом изображение было загружено с использованием необязательных параметров width
и height
в конструкторе new Image()
, вместо element.width
и element.height
вам следует использовать свойства naturalWidth
и naturalHeight
экземпляра картинки (или videoWidth
и videoHeight
, если источником является элемент <video>
), чтобы добиться правильного масштабирования и получения фрагментов картинки.
Аналогично тому, как мы рисуем в canvas изображения с помощью drawImage()
, можно в canvas отображать видео, запустив функцию drawImage()
во время проигрывания видео по событию onplay
:
See the Pen Video with Canvas by LeTea (@letea) on CodePen.
Анимированные изображения на основе спрайтов в canvas
Спрайты - это наборы изображений с определенным шагом. То есть в них одинаковое количество пикселей предполагается на каждое изображение, причем и по горизонтали, и по вертикали. Использовать их можно для анимации персонажа, например. Представьте себе, насколько ресурсоемким будет хранение и загрузка огромного набора изображений, описывающих каждый кадр анимации в игре, если хранить их по отдельности. Вместо этого есть одно изображение, и все позиции персонажа расположены в сетке, как показано ниже.
Чтобы выполнить анимацию, вместо загрузки нового изображения каждую миллисекунду часть того же изображения отображается в окне просмотра только в разных позициях. Для этого на нашем спрайте нужно определить размеры сетки для каждого положения Марио.
Обратите внимание, что вся сетка состоит из ячеек одинакового размера (32 x 39). Но это всего лишь один кадр, который нам нужно будет повторять в коде с помощью функции requestAnimationFrame()
.
Вот пример с анимацией:
See the Pen canvas draw animated image by Elen (@ambassador) on CodePen.
Изменение и сохранение изображения на основе использования canvas
В примере ниже вы сможете загрузить фото и наложить на него фильтры, повернуть или отразить. Кроме того, вы можете сохранить полученное фото после всех манипуляций.
See the Pen Basic Image Editor in JavaScript by Elen (@ambassador) on CodePen.
Примеры изменения изображений с помощью метода drawImage() в canvas
В примере ниже вы найдете "нарезку" оригинального фото на основе функции drawImage()
в canvas
. Довольно интересный эффект, не так ли?
See the Pen Glitch Art with HTML5 Canvas by Dudley Storey (@dudleystorey) on CodePen.
Использование canvas
для фонового изображения с background-size: cover и contain
Используйте переключатели вверху для управления фоновым изображением.
See the Pen Canvas image background size cover & contain by Fabio Ottaviani (@supah) on CodePen.
И второй подобный пример с нарезкой фото и анимацией на странице:
See the Pen Canvas image glitch animation by renatoruk (@renatoruk) on CodePen.
В этом примере при клике ваше изображение разлетится на множество цветных кусочков. Кликните на фото для появления следующей картинки.
See the Pen JavaScript Canvas Effect by Elen (@ambassador) on CodePen.
Эффект появления изображений
Кликните на фото для повторения эффекта.
See the Pen Stretching pixels by Fabio Ottaviani (@supah) on CodePen.
И еще один эффект появления из точек
See the Pen Wolf by massimo (@_massimo) on CodePen.
Маска для изображения
See the Pen Fun with pixels by massimo (@_massimo) on CodePen.
Отображение размытых кадров видео на заднем плане
В этом примере drawImage() позволяет создавать размытое изображение кадра в canvas по мере воспроизведения видео.
See the Pen Video "ambilight" (bias lighting) by Lembit Kivisik (@lembitk) on CodePen.
И еще один вариант воспроизведения видео в canvas на основе drawImage()
. Нажмите и удерживайте кнопку слева, чтобы увидеть оригинальное видео.
See the Pen Pixel manipulation Canvas Video by Elen (@ambassador) on CodePen.
Источники: How displaying an image on HTML5 canvas works и Build An Image Editor in HTML CSS & JavaScript