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-04-17 » 23 сервиса для эффективного экспресс-аудита любого сайта
- 2024-04-08 » Яндекс переходит на новую версию Wordstat
- 2024-04-08 » Яндекс интегрировал в свой облачный сервис эмпатичную нейросеть
- 2024-04-08 » Новая версия нейросети Claude превзошла по мощности аналоги Google и OpenAI
- 2024-04-08 » Как пользоваться GPT 4 и Claude бесплатно и без VPN
- 2024-03-13 » Стратегии SEO на 2024 год
- 2024-03-13 » Как использовать анимацию с помощью JavaScript-библиотеки GSAP
- 2024-03-13 » Использование GSAP 3 для веб-анимации
- 2024-03-13 » Cогласование топографической съёмки с эксплуатирующими организациями
- 2024-02-19 » Теряются лиды? Как настроить сквозную аналитику
- 2024-02-17 » Мерч и IT: на что обратить внимание в 2024 году
- 2024-02-16 » Копируем с RSync: основные примеры синхронизации файлов
- 2024-02-15 » Лучшие noCode AI платформы для создания диалоговых ботов
- 2024-02-14 » Факторы ранжирования Google 2024 — исследование Semrush
- 2024-02-12 » Перенос сайта на другой хостинг
- 2024-02-05 » В России сформирован реестр хостинг-провайдеров
- 2024-02-04 » Использование SSH для подключения к удаленному серверу Ubuntu
- 2024-02-03 » Подключаемся к серверу за NAT при помощи туннеля SSH. Простая и понятная инструкция
- 2024-02-02 » Настройка CI/CD для Gitlab-репозитория: схемы и гайд по шагам
- 2024-02-01 » GitLab CI Pipeline. Запуск сценария через SSH на удаленном сервере
- 2024-01-29 » Introduction to GitLab’s CI/CD for Continuous Deployments
- 2024-01-26 » Настройка GitLab CI/CD
- 2024-01-25 » Установка shell gitlab runner
- 2024-01-25 » Установка и регистрация gitlab-runner в docker контейнере
- 2024-01-25 » Переменные Gitlab-Ci
- 2024-01-25 » Настройка CI/CD в GitLab для синхронизации проекта с веб-серверами
- 2024-01-25 » Копирование файлов scp
- 2024-01-21 » Бездепозитные бонусы от казино: обзор условий и правил использования
- 2024-01-18 » Современная обработка ошибок в PHP
- 2024-01-18 » Пример шаблона проектирования MVC в PHP
Все мы сидим в сточной канаве, но некоторые при этом смотрят на звезды Уайльд Оскар - (1854-1900) - английский писатель |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.