Как создать визуальную библиотеку изображений с HTML5 Canvas
Сегодня утром, открыв почту, получил очередную рассылку от Code Project, в которой был описан интересный путь создания галереи изображений при помощи Canvas элемента. Статья показалась достаточно интересной и я решил опубликовать ее перевод
Прим. от переводчика: Из статьи были убраны некоторые предложения, рекламирующие IE, и некоторые явно очевидные вещи. Сам я не являюсь сторонником браузера IE и не все, описанные ниже способы, идеальны. Но в качестве обзора особенностей HTML5 и попыток нового применения Canvas статья достаточно интересна. Ссылка на статью на code project Ссылка на оригинал
Как фанат пользовательских интерфейсов я не мог упустить возможность разработать что-нибудь с HTML5 Canvas. Этот инструмент предоставляет большое множество новых путей отображения картинок и данных в веб. В этой статье мы пройдем по одному из них.
- Обзор приложения
- Инструменты
- Страница на HTML5
- Получение данных
- Загрузка карт & обработка кеша
- Отображение карт
- Управление мышкой
- Сохранение состояния
- Анимация
- Работа с разными устройствами
- Вывод
Мы сделаем приложение, которое позволит нам отображать коллекцию карт Magic the Gathering ©. Пользователям будут доступны прокрутка и зум при использовании мыши (например, как в Bing Maps).
Готовое приложение можно посмотреть здесь: bolaslenses.catuhe.com Исходники можно скачать здесь: www.catuhe.com/msdn/bolaslenses.zip
Карты сохранены в Windows Azure Storage и используют Azure Content Distribution Network (CDN : сервис, предоставляющий/развертывающий данные рядом с конечными пользователями) для достижения максимальной производительности. ASP.NET сервис используется для возвращения списка карт (используя JSON формат).
ИнструментыДля написания нашего приложения мы будем использовать Visual Studio 2010 SP1 с Web Standards Update. Это расширение добавляет IntelliSense поддержку для HTML5 страниц (это по-настоящему важная вещь). Наше решение будет содержать HTML5 страницу вместе с .js файлами. Про отладку: Visual Studio позволяет устанавливать точки остановки и работать с ними прямо в своей среде.
Отладка в Visual Studio 2010
И так у нас есть современная среда разработки с IntelliSense и поддержкой отладки. Поэтому мы готовы начать и для начала мы напишем HTML5 страницу.
HTML5 страницаНаша страница будет построена вокруг HTML5 canvas, который мы будем использовать для рисования карт: код
- Заголовок с названием, логотипом и специальными ссылками
- Основная часть, содержащая canvas элемент и тултипы, которые будут отображать статус приложения. И скрытое изображение (backImage), используемое как источник для еще не загруженных карт.
Стили — это мощный инструмент, позволяющий создавать бесконечное число отображений.
Наш интерфейс теперь готов и мы можем посмотреть, как получать данные о картах для отображения.
Получение данныхСервер предоставляет список карт, используя JSON формат, по следующей ссылке: bolaslenses.catuhe.com/Home/ListOfCards/?colorString=0 URL принимает один параметр (colorString) для выбора нужного цвета (0 = all). Когда разрабатываешь с JavaScript, хорошо бы посмотреть, что мы уже имеем на сегодняшний день (это справедливо и для других языков программирования, но очень важно именно для JavaScript): вы обязаны задаться вопросом о том, не было ли то, что мы собираемся разработать, уже создано в существующих фрэймворках? И действительно, в мире существует много открытых проектов на JavaScript. Один из них jQuery, который предоставляет изобилие удобных функций. Таким образом, в нашем случае для подключения к URL нашего сервера и получения списка карт мы можем использовать XmlHttpRequest и веселиться с парсингом возвращаемого JSON. Или мы можем использовать jQuery. Мы будем использовать функцию getJSON, которая позаботиться обо всем за нас:
- text — меняет текст тега
- slideToggle — прячет/показывает тег анимацией его высоты
- ID: идентификатор карты
- Path: относительный путь карты (без расширения)
Основной трюк нашего приложения в рисовании только карт, которые видны на экране. Окно отображения определено уровнем зума и отступом (x, y) всей системы.
- Высокое разрешение: 480x680 без компрессии (.jpg суффикс)
- Среднее разрешение: 240x340 со стандартной компрессией (.50.jpg суффикс)
- Низкое разрешение: 120x170 с сильной компрессией (.25.jpg суффикс)
- load: эта функция будет загружать нужную картинку и будет сохранять ее в кеш (msecnd.net url — это адрес карты в Azure CDN)
- getImageForCard: эта функция возвращает картинку из кеша, если она уже была загружена ранее или загружает ее по новой укладывает ее в кеш
Выбор нужного кеша зависит от зума:
Для обратной связи с пользователем мы добавим таймер, который будет управлять тултипом, который отображает количество уже загруженных картинок:
Примечание: лучше использовать jQuery для упрощения анимирования. А теперь перейдем к разговору об отображении карт.
Отображение картДля рисования наших карт нам нужно заполнить элемент canvas используя его 2D контекст (который существует только если браузер поддерживает HTML5 canvas):
Рисование будет выполнено функцией processListOfCards (вызывается 60 раз в секунду):
- Если список карт еще не загружен, мы отображаем подсказку, указывающую что загрузка еще в процессе:
- В последствии мы определяем позицию отображающего окна (в перерасчете на карты и координаты), затем мы очищаем canvas:
- Затем мы отображаем список карт и вызываем функцию canvas контекста drawImage. Конкретное изображение предоставлено активным кешем (зависит от зума):
- Нам также нужно нарисовать полосу прокрутки при помощи функции RoundedRectangle, которая использует квадратичные кривые:
- И наконец нам нужно вычислить число фрэймов в секунду:
Отрисовка карт в основном опирается на возможность браузера ускорять рендеринг canvas элемента. Для примера, это производительность на моей машине при минимальном уровне зума (0.05):
Браузер FPS Internet Explorer 9 30 Firefox 5 30 Chrome 12 17 iPad (при уровне зума 0.8) 7 Windows Phone Mango (при уровне зума 0.8) 20 (!!)
Сайт даже работает на мобильных телефонах и планшетах в том случае, если они поддерживают HTML5.
Здесь мы можем увидеть внутреннюю силу HTML5 браузеров, которые могут обработать полный экран карт больше чем 30 раз в секунду. Это возможно с аппаратным ускорением (hardware acceleration).
Управление мышьюДля нормального просмотра коллекции наших карт нам нужно иметь возможность управления мышью (включая колесико). Для прокрутки мы просто обрабатываем события onmouvemove, onmouseup и onmousedown.
Onmouseup и onmousedown события будут использоваться для слежения за нажатием мыши:
Событие onmousemove подключено к canvas элементу и используется для перемещения вида:
Эта функция (onMouseMove) высчитывает текущую позицию и предоставляет предыдущее значение в случае перемещения сдвига отображающего окна:
Напоминаю, что jQuery также предоставляет инструменты для управлениями событиями мыши. Для управления колесиком придется подстраиваться под каждый браузер в отдельности, поскольку они все работают в этом случае по разному:
Функция регистрации события:
Наконец мы добавим немного инерции во время движения мышки (или во время зума) чтобы придать ощущение гладкости:
Подобную небольшую функции несложно реализовать, но зато она улучшит качество работы с пользователем.
Сохранение состоянияТакже, для того чтобы сделать просмотр удобнее, мы будем сохранять позицию отображающего окна и зум. Чтобы это осуществить мы используем сервис localStorage, который сохраняет пары ключ/значение на долгое время (данные сохраняются после закрытия браузера) и только доступны текущему window объекту:
АнимацияНаша система должна анимировать 3 значения: два отступа (offsets (X, Y)) и зум. Чтобы это сделать, используем функцию, которая будет отвечать за анимацию переменной из исходного до конечного значения с заданной продолжительностю:
Преимущество AnimationHelper в том, что она способна анимировать множество параметров как вы захотите.
Работа с разными устройствамиНаконец мы убедимся, что наша страница может также быть просмотрена на планшетах, ПК и даже на телефонах. Для этого мы используем свойство CSS 3: The media-queries. С этой технологией мы можем применять стили согласно некоторым запросам, таким как конкретный размер экрана:
Здесь мы видим что, если ширина экрана меньше, чем 480 пикселов, то следующий стиль будет добавлен:
Этот стиль будет уменьшать размер заголовка и будет сохранять сайт просматреваемым даже если ширина браузера меньше, чем 480 пикселов (например, на Windows Phone):
ВыводHTML5 / CSS 3 / JavaScript и Visual Studio 2010 позволяют разрабатывать портативные и эффективные решения (в пределах браузера, поддерживающего HTML5) с некоторыми отличными возможностями, такими как аппаратное ускорение рендеринга (hardware accelerated rendering). Такой тип разработки упрощается использованием фреймворков, таких как jQuery.
В заключение скажу, что чтобы убедиться в чем-то — нужно это попробовать!