От автора: В течение уже некоторого времени я изучаю, как можно создать изображение с помехами при помощи веб-технологий html5. В canvas API можно изменять растровые изображения по пикселям, но вчера я осознал, что с помощью довольно простой функции API можно создавать изображения с эффектом графического мусора.
Перенос изображений в Canvas
Начнем мы с тега canvas, как показано в CodePen демо:
1 |
<canvas id="portrait" width="200" height="400"></canvas> |
Обратите внимание, что изначальные размеры тега произвольные. Они будут изменяться при помощи JavaScript. И код CSS:
1 2 3 4 5 6 7 8 |
body { background: #000; } canvas { display: block; margin: 0 auto; width: 60%; } |
JS код для рисования в canvas делится на два общих шага. Первым делом мы загружаем соответствующее растровое изображение:
1 2 3 4 5 |
var img = new Image(); img.src = "nastya.jpg"; img.onload = function() { draw(this); }; |
После полной загрузки изображения мы отрисовываем его на полотно при помощи функции draw. Сначала мы проверяем, чтобы размер полотна совпадал с размером загружаемого изображения:
1 2 3 4 5 6 7 |
function draw(img) { var portrait = document.getElementById("portrait"); var canvas = portrait.getContext("2d"); portrait.setAttribute("width", img.width); portrait.setAttribute("height", img.height); ... } |
Если все нормально, изображение ляжет на canvas один к одному. То есть высота и ширина изображения заполнят такую же по размеру область на холсте, начиная от левого верхнего угла (0, 0) до нижнего правого. Синтаксис будет выглядеть примерно так:
1 2 |
canvas.drawImage(img, 0, 0, img.width, img.height, 0, 0, portrait.width, porttrait.height); |
Пиксели изображения ложатся на холст один к одному, однако примененный CSS код сделает так, что canvas и изображение будут адаптивно подстраиваться под высоту и ширину окна браузера.
Тем не менее, нигде не сказано, что нужно брать все изображение и переносить его на холст целиком сразу. Мы можем нарезать изображение на полоски и выкладывать их на canvas со смещенным горизонтальным значением. Для этого нам понадобится две переменные: количество полосок и максимальное горизонтальное смещение. Код ниже – продолжение функции draw:
1 2 |
var verticalSlices = Math.round(img.height / 20); var maxHorizOffset = 20; |
Полоски отрисовываются внутри цикла for:
1 2 3 4 5 6 7 8 9 10 11 |
for (var i = 0; i < verticalSlices; i++) { var horizOffset = getRandom(-Math.abs(maxHorizOffset), maxHorizOffset); canvas.drawImage(img, 0, i * verticalSlices, img.width, i * verticalSlices + verticalSlices, horizOffset, i * verticalSlices, img.width, i * verticalSlices + verticalSlices); } |
Переменная horizOffset вызывает другую функцию для вычисления случайного значения в пределах двух чисел. Заметьте, что вызов функции может вернуть отрицательное значение, что сдвинет полоски изображения влево:
1 2 3 |
function getRandom(min, max) { return Math.floor(Math.random() * (max - min + 1)) + min; } |
Данная функция создает эффект случайных графических помех, которые вы можете наблюдать в начале статьи.
Заключение
Различные вариации данной техники можно использовать динамически: к примеру, можно наложить на canvas два потока HTML5 видео и сделать сравнение «до-после».
По иронии судьбы, большая часть эффектов позаимствована из аналоговых технологий типа потери сигнала на старых телевизорах, но переведена в цифру. В следующих статьях я покажу еще больше похожих эффектов, которые выполнены при помощи веб-технологий.
Источник: //thenewcode.com/
Редакция: Команда webformyself.