Практический пример: HTML5 в deviantART muro

Майк Дьюи
Mike Dewey

Введение

7 августа 2010 года deviantART отметил свое 10-летие. Мы отпраздновали свой день рождения, запустив инструмент для рисования HTML5 под названием deviantART muro. Этот инструмент можно использовать как отдельное веб-приложение, а также как легкий инструмент для рисования для добавления изображений в комментарии на форуме.

Сообщество deviantART приветствовало этот новый инструмент для рисования с большим энтузиазмом, и сам инструмент теперь получает столько же трафика, сколько некоторые веб-ресурсы приличного размера. С момента запуска новый рисунок отправляется с помощью deviantART muro примерно раз в 5 секунд. Это всего лишь количество выполненных рисунков; многие другие были начаты и не сохранены.

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

Мой фон

В конце 2005 года я был одним из разработчиков, ответственных за инструмент рисования, используемый Draw Here . Этот инструмент представлял собой инструмент «веб-граффити», запускаемый букмарклетом. Его использовали для рисования изображений на любых веб-страницах. Draw Here изначально был создан с использованием SVG (только что вышла бета-версия Firefox 1.5; это был один из первых браузеров, поддерживающих SVG).

В Internet Explorer мы создавали SVG в фоновом режиме, но визуализировали рисунок с помощью VML . В то время WebKit не поддерживал SVG, поэтому я перенес наш код для рендеринга SVG с использованием холста (в то время это была новая технология, доступная только в WebKit). В какой-то момент я даже сделал порт, чтобы наш SVG-код можно было отображать в старых браузерах с помощью набора элементов div, склеенных вместе. (Это, конечно, было скорее шуткой, чтобы показать, что это можно сделать, и использовать его было очень медленно).

В период своего расцвета Draw Here использовался для создания около 100 рисунков в день. Оно было достаточно полным, чтобы его можно было назвать чем-то большим, чем просто экспериментом, хотя оно не имело окончательной доработки, характерной для крупного веб-приложения. В середине 2006 года проект был заброшен, хотя сайт до сих пор хромает — в основном просто ради улыбки.

Технологии, используемые deviantART muro

Поскольку я раньше использовал различные технологии HTML5, меня попросили стать ведущим разработчиком deviantART muro. Любой, кто читает эту статью, вероятно, может понять, почему мы решили использовать HTML5, а не технологию на основе плагинов, такую ​​​​как Silverlight или Flash. Нам хотелось чего-то надежного, а также чего-то, что использовало бы открытые стандарты.

Выбор между Canvas и SVG

Мы решили создать слой рисования с помощью холста. Некоторые люди могут задаться вопросом, когда им следует использовать Canvas, а когда — SVG. Возможности этих двух технологий во многом совпадают: как доказала Draw Here, обе технологии можно использовать для создания приложения для рисования.

Я обнаружил, что SVG отлично подходит, если вы хотите сохранить дескрипторы нарисованных вами объектов. Например, если вы хотите, чтобы пользователь мог рисовать линию, а затем перетаскивать ее фрагменты, чтобы изменить ее форму, это было бы довольно тривиально с использованием SVG. Но то же самое очень неудобно использовать холст.

Когда вы используете холст, вы запускаете что-то на холст, а затем забываете об этом. Пустой холст и тот, на котором рисовали в течение часа, в коде действуют одинаково, и они занимают примерно одинаковый объем памяти. Хотя программы растрового рисования обычно очень хорошо работают с огнем и забывают о технологиях, некоторые вещи они действительно усложняют. Например, создать функцию быстрой отмены в Canvas гораздо сложнее, чем в SVG. В SVG вы можете просто сохранить дескриптор нескольких последних строк, которые вы разместили, а для отмены достаточно просто удалить эти объекты. В случае с холстом после того, как линия была нарисована, вы не знаете, что было под ней, поэтому для удаления линии необходимо перерисовать область, в которой она находилась.

Как только мы стиснули зубы и решили, что в качестве холста будет использоваться HTML5, мы решили использовать и другие HTML5-фишки здесь и там. Примером этого является то, как мы использовали localStorage для отслеживания настроек кисти пользователя. Таким образом, как только они настроят различные кисти так, как им нравится, они смогут вернуться к этим настройкам в следующий раз, когда воспользуются нашим инструментом. localStorage означает, что нам не нужно использовать наши файлы cookie или совершать какие-либо обращения к серверу, чтобы получить эти настройки.

Использование холста

Холст прошел долгий путь за последние пять лет. В Draw Here мы фактически не публиковали мой порт Canvas, потому что производительность была плохой. Теперь, я думаю, можно с уверенностью сказать, что он, вероятно, работает лучше, чем вы себе представляете. Очистка большого участка холста и перерисовка сложных фигур обычно происходит со скоростью, превышающей человеческое восприятие. Единственное, что мне иногда кажется слишком медленным, — это использование getImageData() для выборки пикселей. Скорость операции, очевидно, зависит от размера холста, но на большом холсте выполнение getImageData() в неподходящее время может занять достаточно много времени, чтобы пользователь почувствовал, что приложение отвечает медленно.

После прочтения различных руководств по холсту у меня изначально сложилось впечатление, что это тяжелая вещь, которую следует использовать с осторожностью, может быть, один или два раза на странице. Не знаю, все ли понимают это, но я понимал, поэтому использовал его экономно, когда мы впервые начали кодировать deviantART muro. Однако через некоторое время я обнаружил, что есть много маленьких мест, где холст может сэкономить вам много усилий. Например, в макетах нашего приложения указано, что палитра цветов должна представлять собой два перекрывающихся треугольника, показывающие основной и дополнительный цвета:

Выбор цвета
Выбор цвета

Моим первым инстинктом было начать думать о том, как создать эту маленькую штуковину пользовательского интерфейса с помощью традиционных HTML и CSS. Люди, которые хорошо разбираются в CSS, могли бы указать, как все это можно сделать с помощью CSS, но треугольная форма двух частей, меняющих цвет, делает это не таким очевидным.

Когда мне пришло в голову просто использовать холст, я сделал виджет с одним элементом DOM и парой строк JavaScript. deviantART muro повсюду использует узлы холста. Каждый слой представляет собой холст, и изменение порядка слоев — это всего лишь вопрос переключения z-индекса. Палитра «навигатор» масштабирования, показывающая уменьшенное изображение области рисования, — это просто еще один холст, который иногда вызывает функцию drawImage(), используя холсты слоев в качестве исходных изображений. Даже курсор области рисования (двухцветный круг, размер которого регулируется в зависимости от размера кисти и масштаба) представляет собой холст, который плавает под мышью.

Причина, по которой мы более либерально относились к холсту, чем к другим технологиям HTML5, заключается в том, что библиотека Google ExplorerCanvas позволяет имитировать холст в Internet Explorer. Это подводит меня к следующему разделу.

Интернет Эксплорер (IE)

Основная причина того, что большинство крупных веб-сайтов пока не используют HTML5, заключается в том, что они не хотят терять своих пользователей Internet Explorer. Я уверен, что первый вопрос, который возникает у большинства разработчиков, когда они слышат, что deviantART создал приложение для рисования HTML5, звучит так: «Что было сделано с IE?»

Вначале мы решили, что приложим все усилия, чтобы заставить все работать в Internet Explorer, но мы закончили с использованием стиля веб-разработки с наименьшим общим знаменателем. Поскольку веб-сообщество придерживается подхода, согласно которому сайт не может запуститься, пока он не будет выглядеть одинаково во всех известных браузерах, пользователи не могут определить, когда их браузер отсутствует. Для обычного пользователя проблемы со скоростью связаны с его интернет-соединением, и каждая страница отображается более или менее одинаково. Поэтому они выбирают свой любимый браузер, основываясь на произвольных мелочах пользовательского интерфейса, таких как цвет кнопки «Назад».

Мы решили, что создадим любую интересную функцию, которая придет в голову, используя спецификацию HTML5, попробуем заставить ее работать в Internet Explorer, а если она не сможет работать, мы просто выскочим модальное окно, объясняющее, что эта функция недоступна, потому что их браузер еще не реализовал веб-стандарт.

Сначала мы пытались заставить все работать с помощью ExplorerCanvas от Google (exCanvas). Он на удивление хорошо имитирует холст для большинства вещей. Однако у него есть один недостаток. Каждый штрих, сделанный на холсте, является объектом DOM в базовом переводе VML. Для большинства вещей, которые вы можете попробовать использовать на холсте, это нормально, но некоторые кисти deviantART muro создают фигуры путем наложения множества мазков вместе. Когда Internet Explorer сталкивается с VML, содержащим тысячи узлов (даже на быстрой машине), он падает и умирает. Из-за этого для многих вызовов рисования нам фактически приходилось писать код на реальном VML и использовать трюки, в которых мы объединяли узлы вместе и использовали команду перемещения, чтобы указать, где должны быть пробелы. Многие небольшие элементы управления и тому подобное в интерфейсе используют тег холста, поскольку эти небольшие элементы обычно хорошо работают с exCanvas.

Помимо того, что некоторые функции работают с exCanvas, мы предложили пользователям продолжать использовать свою версию Internet Explorer, если они установили подключаемый модуль Google Chrome Frame . Google Chrome Frame — это плагин, который встраивает механизм рендеринга Google Chrome в Internet Explorer. С точки зрения пользователя, он по-прежнему использует знакомый ему браузер; но под обложкой наша страница отображается с помощью возможностей Chrome HTML5 и более быстрого JavaScript.

Я знал, что портировать вещи для работы с Chrome Frame должно быть легко, но я не осознавал, насколько это просто. Вы просто вставляете дополнительный метатег и… и все, в IE все начинает работать.

Краткое содержание

Очень приятно работать с новыми технологиями в спецификации HTML5, и я бы сказал, что все, что я использовал, определенно готово к использованию в прайм-тайм. Даже если вам нужно, чтобы что-то работало в IE безупречно, существует удивительное количество вещей, которые вы можете сделать, объединив Canvas и exCanvas. И написать слой перевода между SVG и VML также на удивление выполнимо. Как только вы начнете использовать эту технологию, это будет похоже на попадание в совершенно новый мир.

Рекомендации