[Из песочницы] Как я png в 4 раза уменьшал

Эта идея возникла год назад, когда мне на просчет пришел проект веб-игры с большим количеством анимации, которую предполагалось делать спрайтами в хорошем качестве (большими спрайтами) и с качественным альфаканалом (в смысле, не с индексированным цветом прозрачности). В этой игре вы бросаете кости на стол и надо, чтобы они падали всегда по разному.Сделать одну такую png-анимацию размером одного кадра 400 на 400 мне, как в том числе аниматору, не составляло труда. Сделать сбрасывание кубиков всегда разным представлялось задачей нетривиальной ни в одном месте. Однако замотивированный круглой суммой из волосатых рук я начал штурм, думая в первую очередь о том, как сделать игру одновременно и красивой (так как изначально я дизайнер, трехмерщик и эстэт, а программистом не стану никогда), и такой, которая загрузится меньше чем за тысячу минут.Желая оценить объем графических файлов анимаций, я сделал вариацию падения одного кубика в полоске, чтобы потом сбрасывать несколько подобных вариаций под разными углами и, возможно, это было бы достаточно разнообразно. Когда я собрал секвенцию кадров в горизонтальную полоску, мысль о GIF, его горизонтальным сжатии и индексированных цветах зажглась сразу же и отпустила только вчера вечером.

По своему опыту специалиста по анимации трехмерных кубиков я знаю, что пока они скачут и всячески анимируются, важность качества отображения их краев и других деталей обратно пропорциональна скорости. Поэтому где-то их можно пожать по максимуму как в альфе, так и в rgb, а на кадрах, где движение успокаивается и кубик встает — делать уже на 100%. То есть png со своими огромными размерами востребован только в последних 5–10 кадрах из 50-кадровой секвенции — и только в том месте кадра, где остановился кубик. Желание пожать все, что можно, напрашивается само собой.

throw

Делая вариацию падения кубика я допустил, что потом для него можно будет сделать один альфа-канал и шесть rgb-вариантов с разными текстурами (разными финальными значениями кубика). Пока кубик летит, он летит по прямой, после первого удара он чуть отклоняется, а потом отклоняется сильно, поэтому полоска кадра получается не такой тонкой, как хотелось бы, и большая часть каждого кадра остается пустой, что болезненно для png, но не было бы проблемой для gif. В итоге со всеми ухищрениями на один вариант в формате png32 потреблялось полмегабайта килобайтов. Это не учитывая, что таких вариаций падения надо было еще, скажем, штук 10 хотя бы, и в игре ожидалась куча другой графики.

Но вдруг! В тот момент, когда я уже вошел во вкус какие-то прекрасные люди предложили заказчику сделать заказ на 7 копеек меньше и заказ сбрился, а все написанное выше лишилось логического конца. Неприятно, да? Однако я остался с пониманием четко очерченной проблемы: альфа-канал в современных больших и красивых изображениях используется подчас до безобразия расточительно и с пониманием как эту проблему можно решить.Я подождал год, потом сел, нашел эту статью, взял из нее весь код, вставил в случайные места точки с запятой и получился javascript-плагин, который может творить, согласно моему воспаленному воображению, чудовищные вещи с анимацией на сайте, уменьшить трафик полноцветных RGBA изображений в 2–10 раз и перевести использование больших RGBA изображений на сайте в плоскость разумного. Также в него сразу зашита функция нарезки на спрайты, поэтому он может оказаться полезен для тех счастливцев кто озабочен front-end оптимизацией.

Матчасть Предполагается, что вы умеете вытащить из имеющегося изображения с прозрачностью черно-белый альфа канал и пожать его самостоятельно в соответствии со своими пожеланиями к качеству и размеру.В ходе загрузки страницы вызывается функция alpha_spriter и в нее подаются 4 атрибута:

URL rgb-файла со спрайтами URL соответствующего файла с альфа-каналом в опять же любом формате, в большинстве случаев это gif / png8.Оба файла должны быть на этом же домене. Javascript-объект вольной формы с разметкой спрайтов. Штука, форма достаточно точна и её пример доступен в коде плагина. Ну и функция, какую хотите по завершению В ту же секунду функция загружает изображения, совмещает их с помощью canvas в полноценный png32 и режет на спрайты. На выходе сгенеренные изображения назначаются по id (указанным в объекте JS), заготовленным в теле документа элементам в двух вариантах: src для , либо background-image (поверх уже установленных других необходимых свойств фона).Минимальная первая рабочая версия незамедлительно опробована и успешно совмещает на живом проекте изображение танцующего снежного барса, местами напоминающего петуха и таким образом спасает it-инфраструктуру одной страны от необратимого перегрева.

compare

Прилагаю для сравнения хронометраж загрузки страницы. Сама страница, плагин и тестовые файлы могут быть найдены на гитхабе, если это здесь не запрещено. Если запрещено — просто не нажимайте, пожалуйста.

time

На всякий случай еще раз обратите внимание, что у меня канвас делал свое дело в условиях веб-окружения и только со своего origin. Этот момент уточняется.

Всё А теперь расскажите мне, что таких решений уже 10 и они никому не нужны. Про rgb8 и про альфу в css. Ну, а если серьезно, то хотелось бы в первую очередь понять, насколько это востребовано и в случае чего допиливать до уровня hi-end 3000 и делать генератор sprite map. Ну и, собственно, если у вас есть пожелания — велкам.Спасибо!

Список литературы Та самая статья, послужившая ускорению разработки плагина и, возможно, обусловившая его появление — спасибо, sergof!

© Habrahabr.ru