This post is also available in: Английский
Портирование web приложений изначально созданных на Flash, задача не простая, но не бесперспективная. В данной статье мы рассмотрим несколько моментов миграции с Flash на HTML5 средства, и сопутствующие подводные камни.
В настоящее время все большую популярность в нашей стране и в мире набирают мобильные продукты Apple. Однако, как мы знаем, у компании Apple не наладилась дружба с решениями Adobe.
Количество пользователей использующих продукты Apple (iPhone / iPad) слишком велико, чтобы не обращать на них внимание. Для этого нужно воспроизвести функционал Adobe Flash подручными средствами доступными в Mobile Safari. Средства эти, если не исчерпывающие, то очень близки к этому. В конце концов работать предстоит всего с одним браузерным движком.
В WebKit мы получаем массу средств CSS3, что не мало: тени, градиенты, прозрачность и многое другое. Кроме того, сам движок WebKit рожденный в свободном проекте KDE стараниями Apple и Google данный момент является наиболее продвинутым в плане HTML5, а с поправкой на аппаратные возможности декодирования видео, воспроизведение HTML5-видео, как минимум не является проблемой, а в целом, даже дает преимущества в сравнении с другими платформами. Например, если ваше видео демонстрируемое во Flash плеере закодировано в h.264, то в общем случае вам не потребуется перекодирование.
Дизайн штатного плеера в iOS достаточно универсален, и его функциональность на 100% покрывает функциональность типичного плеера созданного с использованием Flash. Однако, дизайн иногда хочется иметь оригинальный.
При портировании Flash плеера были использованы векторные элементы оригинального плеера экспортированные в формат SVG. WebKit поддерживает SVG версии 1.1 и позволяет анимировать векторную графику посредством SMIL или ECMAScript (фактически применим Javascript). А это уже то, с чего начинался Flash.
Пример вращения элемента изображения в SVG средствми ECMAScript:
<script> <![CDATA[ var deg=0; function rot() { document.getElementById('stuff').setAttribute( "transform","rotate("+deg+" 28 28)" ); setTimeout("rot()", 1); deg++; if (deg>360) deg=0; } function init() { rot() } ]]> </script>
Или SMIL:
<g> <animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0 28 28" to="360 28 28" begin="0s" dur="3s" repeatCount="indefinite"/> <use xlink:href="#stuff"/> </g>
Не забудте упомянуть xlink: <svg ... xmlns:xlink="http://www.w3.org/1999/xlink">
Однако испытав эйфорию анимировав векторный рисунок, мы спотыкаемся сразу о два подводных камня: если мы вставляем svg на страницу в тэге <img> (что нормально для WebKit) то у нас не воспроизводится анимация. Если мы используем легализованный в html5 тэг <embed>, то мы натыкаемся на баг в WebKit и теряем прозрачность фона. Таким образом, первый подводный камень мы обходим используя второй, а второй мы преодолеваем внедрением в SVG-код стиля:
<style> svg { -webkit-background-clip: text; } </style>
Надо заметить, что у устройств с тачскрином, в том числе мультитач, нет клавиатуры и мыши. Тачскрин генерирует совершенно иные события, кроме того и сам браузер на эти события реагирует вызывая изменения масштаба и прокрутку страницы.
Таким образом, портирование с Flash-слайдера изображений на JavaScript — это только начало. Так-же надо озаботится обработкой нужных событий. Это позволит избежать неожиданного поведения браузера, а такие события еще больше обогатят наше приложение. Упростить разработку помогут Javascript фрэймворки. Например для jQuery существует несколько плагинов обеспечиваюх поддержку жестов iPhone и iPad.
И вот мы уже имеем полнофункциональный слайдер который работает на iPad.
Работает-то работает, но тормозит. Скорость работы JavaScript на устройствах Apple оставляет желать лучшего.
Что можно в таком случае сделать? Учитывая что мы работаем все-таки с WebKit, разумным решением будет снять обязанности конкретно анимации с JavaScript, и воспользоваться анимационными возможностями CSS3. Так что анимацию мы прописываем в CSS, а в JavaScript только слушаем события и назначаем классы элементам.
Пример такой анимации:
<!DOCTYPE HTML> <html> <head> <meta name="viewport" content="initial-scale=1.0; maximum-scale=1.0; user-scalable=0;" /> <title>iPhone JS testing</title> <style type="text/css"> .box{ position: absolute; width: 150px; height: 150px; background-color: red; -webkit-transition-property: -webkit-transform; -webkit-transition-duration: 2.0s; } .move{ -webkit-transform: translateX(100px); } </style> <script src="jquery-1.3.2.min.js" type="application/x-javascript"></script> </head> <body> <script type="text/javascript"> $(function () { $(".box").click(function(){ $(this).addClass("move"); }); }); </script> <div class="box"></div> </body> </html>
Теперь, когда у нас есть все составляющие для замещения выразительных свойств Flash, вернемся к HTML5 видео плееру. Из атрибутов и событий DOM элемента video, хотелось бы отметить следующие:
currentTime и duration (float, в секундах) позволяют реализовать ползунок воспроизвидения, который можно не только наблюдать, но и перемещать, так как в currentTime можно записать желаеме время.
readyState (int) дает иформацию о готовности к проигрыванию видео:
0 Данных (пока) нет
1 Известна продолжительность
2 Известны данные для текущей позиции
3 Имеются данные для текущей и будущей позиции — с этого момента можно начинать воспроизведение
4 Имеются данные для воспроизведеня всего видео
Ну и конечно основные события которые управляют воспроизведением: play и pause. Все остальное по сути дело техники.
К сожалению, duration не всегда выдает корретный результат: иногда мы можем получить NaN вместо нужного значения, так что разумнее будет сообщить нашему скрипту продолжительность видео заранее.
Напоследок стоит упомянуть о форматах и контейнерах которые поддерживает iPad и iPhone. В общем слчае это: видеокодек — h.264, аудиокодек — aac. Контейнеры mp4, m4v, mpeg-ps. Подробнее на сайте Apple
Пример HTML5 плеера созданного с использованием вышеперечисленных технологий. Для корректной работы на компьютере требуется браузер на основе Webkit: Apple Safari или Google Chrome