ASCII анимация с помощью спрайта, элемента canvas и JavaScript
В данном уроке мы сделаем эффектное преобразование спрайта в анимированную ASCII картинку (то есть в изображение, нарисованное с помощью символов). Для реализации задуманного нам понадобится элемент canavas и несколько строк кода на JavaScript.
Шаг 1. Разметка HTML
Для создания эффекта нам понадобится следующая структура:
<!-- Источник изображения для конвертации --> <img src="/lessons/les1534/img/sprite.png" id="sprite"/> <div id="container"> <!-- ASCII часть будет выводиться в ниже представленный тег pre --> <pre id="ascii"></pre> </div>
Изображение содержит исходный спрайт. Весь функционал будет реализован в коде JavaScript, а результат конвертации будет выводиться в элемент ascii.
Шаг 2. Создаем временные элемент canvas
window.onload = function(){ //Переменные для обработки спрайта var sprite = document.getElementById("sprite"); var W = sprite.width; var H = sprite.height; //Элемент canvas для обработки спрайтов var tcanvas = document.createElement("canvas"); tcanvas.width = W; tcanvas.height = H; //Размеры элемента canvas такие же, как и у исходного спрайта var tc = tcanvas.getContext("2d"); //Выводим изображение в элемент canvas tc.drawImage(sprite, 0, 0, W, H); sprite.parentNode.insertBefore(tcanvas, sprite); //одновременно выводятся элемент canvas и исходное изображение }
Скрипт создает элемент canavas и выводит в него и сходный спрайт.
Шаг2. Преобразуем спрайт в серый вариант и готовим ASCII данные
window.onload = function(){ //Внутренние переменные var r, g, b, gray; //Переменные для обработки спрайта var sprite = document.getElementById("sprite"); var W = sprite.width; var H = sprite.height; //Элемент canvas для обработки спрайтов var tcanvas = document.createElement("canvas"); tcanvas.width = W; tcanvas.height = H; //Размеры элемента canvas такие же, как и у исходного спрайта var tc = tcanvas.getContext("2d"); //Выводим изображение в элемент canvas tc.drawImage(sprite, 0, 0, W, H); //Получаем данные о пикселях var pixels = tc.getImageData(0, 0, W, H); var colordata = pixels.data; //Каждый пиксель дает 4 целых числа -> r, g, b, a //Поэтому длина массива colordata будет W*H*4 for(var i = 0; i < colordata.length; i = i+4) { r = colordata[i]; g = colordata[i+1]; b = colordata[i+2]; //Конвертируем цвет в серую шкалу gray = r*0.2126 + g*0.7152 + b*0.0722; //Переписываем массив colordata полученными данными //colordata[i] = colordata[i+1] = colordata[i+2] = gray; } //Выводим серое изображение tc.putImageData(pixels, 0, 0); //Вы можете увидеть серое изображение спрайта //с помощью вставки элемента canvas в структуру DOM sprite.parentNode.insertBefore(tcanvas, sprite); //одновременно выводятся элемент canvas и исходное изображение }
Теперь на основании серого варианта спрайта готовим текст для ASCII картинки. Готовим массив, в котором строчки символов соответствуют строчкам пикселей. На основании значения интенсивности серого цвета выбирается символ. Полученные строки добавляются в структуру DOM.
window.onload = function(){ //Внутренние переменные var r, g, b, gray; var character, line = ""; //Переменные для обработки спрайта var sprite = document.getElementById("sprite"); var W = sprite.width; var H = sprite.height; //Элемент canvas для обработки спрайтов var tcanvas = document.createElement("canvas"); tcanvas.width = W; tcanvas.height = H; //Размеры элемента canvas такие же, как и у исходного спрайта var tc = tcanvas.getContext("2d"); //Выводим изображение в элемент canvas tc.drawImage(sprite, 0, 0, W, H); //Получаем данные о пикселях var pixels = tc.getImageData(0, 0, W, H); var colordata = pixels.data; //Каждый пиксель дает 4 целых числа -> r, g, b, a //Поэтому длина массива colordata будет W*H*4 var ascii = document.getElementById("ascii"); for(var i = 0; i < colordata.length; i = i+4) { r = colordata[i]; g = colordata[i+1]; b = colordata[i+2]; //Конвертируем цвет в серую шкалу gray = r*0.2126 + g*0.7152 + b*0.0722; //Переписываем массив colordata полученными данными //colordata[i] = colordata[i+1] = colordata[i+2] = gray; //Текст для ascii картинки. //Темные цвета = символы подобные "W", "@" //Светлые цвета = "`", "." if(gray > 250) character = " "; //Почти белый else if(gray > 230) character = "`"; else if(gray > 200) character = ":"; else if(gray > 175) character = "*"; else if(gray > 150) character = "+"; else if(gray > 125) character = "#"; else if(gray > 50) character = "W"; else character = "@"; //Почти черный //Новые строки и вставка в DOM if(i != 0 && (i/4)%W == 0) //если указатель достиг конца строки { ascii.appendChild(document.createTextNode(line)); //Новая строка ascii.appendChild(document.createElement("br")); //Очищаем строку для следующего набора пикселей line = ""; } line += character; } //Выводим серое изображение tc.putImageData(pixels, 0, 0); //Вы можете увидет серое изображение спрайта //с помощью вставки элемента canvas в структуру DOM sprite.parentNode.insertBefore(tcanvas, sprite); //одновременно выводятся элемент canvas и исходное изображение }
Самое время добавить некоторые стили для формирования. Нам нужно скрыть исходный спрайт и выровнять полученную ASCII картинку с помощью моноширинного шрифта.
#ascii { font-family: monospace; font-size: 11px; line-height: 70%; } #sprite { display: none; }
Также отключаем в скрипте вывод элемента canvas.
Шаг 5. Анимация
Анимация осуществляется за счет изменения значения левого поля. Полученное изображение смещается и в контейнере с соответствующими свойствами последовательно сменяются кадры.
Контейнер имеет следующие свойства.
#container { overflow: hidden; display: inline-block; }
А в скрипте будут производиться расчеты и установка значений. Для смены кадров используется таймер.
window.onload = function(){ //Внутренние переменные var r, g, b, gray; var character, line = ""; //Переменные для обработки спрайта var sprite = document.getElementById("sprite"); var W = sprite.width; var H = sprite.height; //Элемент canvas для обработки спрайтов var tcanvas = document.createElement("canvas"); tcanvas.width = W; tcanvas.height = H; //Размеры элемента canvas такие же, как и у исходного спрайта var tc = tcanvas.getContext("2d"); //Заполняем элемент canvas белым сплошным полем перед работой с png tc.fillStyle = "white"; tc.fillRect(0, 0, W, H); //Выводим изображение в элемент canvas tc.drawImage(sprite, 0, 0, W, H); //Получаем данные о пикселях var pixels = tc.getImageData(0, 0, W, H); var colordata = pixels.data; //Каждый пиксель дает 4 целых числа -> r, g, b, a //Поэтому длина массива colordata будет W*H*4 var ascii = document.getElementById("ascii"); for(var i = 0; i < colordata.length; i = i+4) { r = colordata[i]; g = colordata[i+1]; b = colordata[i+2]; //Конвертируем цвет в серую шкалу gray = r*0.2126 + g*0.7152 + b*0.0722; //Переписываем массив colordata полученными данными //colordata[i] = colordata[i+1] = colordata[i+2] = gray; //Текст для ascii картинки. //Темные цвета = символы подобные "W", "@" //Светлые цвета = "`", "." if(gray > 250) character = " "; //Почти белый else if(gray > 230) character = "`"; else if(gray > 200) character = ":"; else if(gray > 175) character = "*"; else if(gray > 150) character = "+"; else if(gray > 125) character = "#"; else if(gray > 50) character = "W"; else character = "@"; //Почти черный //Новые строки и вставка в DOM if(i != 0 && (i/4)%W == 0) //если указатель достиг конца строки { ascii.appendChild(document.createTextNode(line)); //Новая строка ascii.appendChild(document.createElement("br")); //Очищаем строку для следующего набора пикселей line = ""; } line += character; } //Выводим серое изображение //tc.putImageData(pixels, 0, 0); //Вы можете увидет серое изображение спрайта //с помощью вставки элемента canvas в структуру DOM //sprite.parentNode.insertBefore(tcanvas, sprite); //одновременно выводятся элемент canvas и исходное изображение //Анимация var frames = 10; //Спрайт имеет 10 кадров var container = document.getElementById("container"); //Ширина контейнера должна быть равна только одному кадру var frame_width = parseInt(window.getComputedStyle(container).width)/frames; //window.getComputedStyle поддерживается в Chrome, FF, Opera и IE9+ //Значение ширины имеет "px" в конце, поэтому parseInt используется для удаления суффикса container.style.width = frame_width+"px"; //Будем изменять margin-left элемента ascii для смещения. ascii.style.marginLeft = "0"; setInterval(loop, 1000/10); function loop() { var current_ml = parseFloat(ascii.style.marginLeft); //Если ascii достиг последнего кадра (9-го в нашем случае) //Значение поля нужно установить в 0 //frame_width * (10-1) * -1(так как мы используем отрицательное значение поля) if(current_ml == frame_width*(frames-1)*-1) ascii.style.marginLeft = "0"; else ascii.style.marginLeft = (current_ml - frame_width) + "px"; } }
Готово!
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/qvzUUKScQKs/lessons.php
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
- 2024-05-27 » Подборка сервисов для расшифровки аудио в текст
- 2024-05-27 » PostgreSQL 16. Изоляция транзакций. Часть 2
- 2024-05-06 » Как настраивать конверсионные стратегии: работа над ошибками
- 2024-04-22 » Комментирование кода и генерация документации в PHP
- 2024-04-22 » SEO в России и на Западе: в чем основные отличия
- 2024-04-22 » SEO для международного масштабирования
- 2024-04-22 » Как использовать XML-карты для продвижения сайта
Кто мало хочет, тот дешево стоит |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.