HTML, CSS, JS

Будущее видео
в веб-дизайне

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

Но как интегрировать видео в приложение или на страницу? Как это будет выглядеть и как это воплотить в жизнь? В этой статье вы найдёте вдохновение, способ исполнения  и технические особенности, чтобы начать использовать современное видео в вебе.

Когда видео избавляется от ограничений

Видео, комбинированное с анимацией, является мощным инструментом для инновационного и неотразимого UX. Только представьте интерактивные скринкасты и подсказки, в которых элементы DOM-структуры перетекают по странице синхронно с подсказками. Почему бы не совместить видео с анимацией, чтобы показать новым пользователям ваше приложение? Как насчёт включить видео о том, что вы продаёте на странице сайта, заменив статичные «жипеги»? Стоит лишь немного увлечься и видео станет чем-то большим, чем просто мигающая бирка, вида «купи меня». Далее несколько прекрасных, вдохновляющих примеров видео, интегрированных в дизайн.

Новая промо-страница компании Apple для MacPro — это ошеломляющий пример видео, которое «вырвалось за рамки» и идеально вписалось в контент. Новый MacPro, акцентирует на себя внимание в центре страницы. Но стоит прокрутить колесом мыши, как он начинается вращаться и разбираться на составляющие, а плавно появляющиеся подсказки рассказывают о том, что вы сейчас наблюдаете.

macpro

Как вставить видео в дизайн?

Если вы осмелитесь на видео и анимацию в своём следующем проекте у вас не будет много источников, на которые можно опираться при разработке. Не канонической, простой в использовании, opensource библиотеки для синхронизации видео с анимацией не существует, поэтому все решения отличаются друг от друга. Нужно использовать Javascript или обойтись только CSS keyframe анимациями и transition-ами? Размещать видео на сервере проекта и использовать преимущества HMTL5 тега video и события, привязанные к нему или воспользоваться YouTube-ом или Vimeo? И как, в конце концов, привязать анимации к видео?

Вместе мы найдём ответы на вышеупомянутые вопросы по мере того, как изучим микро JavaScript framework. Charlie.js обеспечит нас лёгкой в использовании API для синхронизации видео и CSS3 анимаций.

Лучший способ понять — сделать, так что поехали.

Что делает Charlie.js?

Нам нужен способ создания анимации и последующего её вызова в определённые моменты видео. Также нам нужно будет приостанавливать анимацию, если видео остановлено. И ещё способ переключения видео на разные временные участки.

Чтобы ограничить сферу применения данной статьи, мы будем использовать с Charlie.js только CSS анимации. JavaScript библиотеки анимации более гибкие и функциональные, но keyframe синтаксис привлекателен своей простотой для понимания, а его эффекты имеют аппаратное ускорение. Использовать для таких целей исключительно CSS анимации — хороший выбор для небольших проектов.

Чтобы сохранить простоту использования, Charlie.js поддерживает только одно видео на странице.

По мере того, как мы будем проходить через создание этой библиотеки помните, что используя этот фреймворк мы только изучаем CSS анимации и видео в вебе. Конечная цель — изучить, а не создать качественный код для продакта.

Становление API

Для нашего небольшого фреймворка есть смысл разобраться с API в первую очередь. Иными словами, нам нужно понять, как кто-то использовал бы библиотеку, а потом написать скрипт исполнения API.

Библиотека видео и анимации может работать по разному, но основная загвоздка в том, как прикрутить анимацию к видео. Как разработчику указать какие анимации должны применяться к каким элементам и в какой момент времени видео это должно происходить?

Один из вариантов — слить данные в JSON или XML. Противоположным решением будет не разделять данные и поместить все конфигурации в вызовы функций на чистом JavaScript. Оба варианта хороши, но есть и нечто среднее.

Обычно, CSS анимация определяет в таблице стилей. Идеально, когда она определена для Charlie.js, не в JSON файле. Это имеет смысл и у этого решения есть преимущества. Когда анимация находится в таблице стилей, её можно протестировать без полной загрузки видео и библиотеки анимации.

Анимации привязаны к элементам, у которых есть data-атрибуты. Data-атрибуты же определяют имя анимации, а также задают время начала проигрывания.

Предположим, у вас есть CSS анимация под названием fade, для плавного затухания (через понижение прозрачности), и другая анимация — fling, для смещения элементов за пределы страницы. И вы хотите применить к блоку на странице обе эти анимации, продолжительностью 3 секунды в видео. Разметка должна выглядеть так:

<div class="charlie" data-animations="fade, fling" data-times="3, 3"> ... </div>

Charlie.js запустит данные анимации, когда видео дойдёт до 3-х секунд.

fade и fling анимации определены в таблице стилей, подключенной к документу.

А вот так  fade анимация может выглядеть в CSS (префиксы браузеров здесь не написаны, но всё же требуются для Chrome и Safari):

листинг кода

Класс .fade — это то, через что Charlie.js запускает fade анимацию, присваивая данный класс к анимируемому элементу.

Видео-хостинг: HTML5 vs. Flash и Silverlight

Когда с API разобрались, следующим вопросом встаёт хостинг видео. Хостинг определяет, в какую оболочку будет обёрнуто видео и от этой оболочки будет зависеть, что мы сможем с ним сделать.

Видео, встроенное при помощи Flash или Silverlight ограничит варианты дизайна, поэтому сервис видео-хостинга должен поддерживать HTML5 video тэг.  video тэг проще всего стилизовать и расположить на странице. Можно применить CSS фильтры и трансформации, а также CSS анимации прямо к видео. К тому же стандартные медиа-события надёжные и обеспечивают множество способ, чтобы привязать свой код к видео. Большим недостатком тега video является совместимость. Он не работает в IE8. Ну и чёрт с ним!

Какие виды видео-хостинга должна поддерживать Charlie.js? Строение библиотеки делает возможной поддержку нескольких вариантов хостинга. Например, Popcorn.js (прекрасная библиотека для синхронизации видео и контента) поддерживает несколько вариантов хостинга и API. Но, чтобы сохранить её простоту, наша маленькая библиотека будет поддерживать только встроенный HTML5  video тэг. Что-либо в iframe или flash-контейнере не будет поддерживаться.

Это, конечно, хорошо для Charlie.js, но что, если вы застряли (в прошлом десятилетии), поддерживая старые браузеры и вынужденны иметь дело с видео, завёрнутым в iframe? Большинство компаний видео-хостинга обладают приличным API. В крайнем случае, вы будете вынуждены использовать их API, чтобы синхронизировать свою анимацию. YouTube и Vimeo — самые популярные сервисы и оба предлагают обширные API для использования. Ещё есть такой прекрасный вариант, как Wistia, но он менее известный.

Если же хотите использовать исключительно video тэг, но не хотите располагать видео на своём хостинге, обратите внимание на Vid.ly. Загрузите видео и Vid.ly перекодирует его в любой необходимый формат и выдаст универсальный URL для вставки в video тэг, который автоматически выберет необходимый видео-формат, в соответствии с браузером пользователя.

листинг кода

Предостережение

JavaScript в большинстве данных сниппетов использует Underscore; такие вещи, как _.forEach и _.toArray являются функциями из этой библиотеки. Underscore поощряет функциональный стиль программирования, который может удивить вас, если вы никогда не сталкивались с ним ранее. Но немного потраченного на изучение времени сэкономит уйму времени и строк кода в будущем. Лучше не проверять это на своём опыте. Далее вы встретите комментарии в коде, которые будут описывать, что происходит. Должно быть достаточно легко для понимания.

Ещё один нюанс: этот код запустится в большинстве современных браузеров, но никто не делал его кроссбраузерным для примера. Если ваш проект требует синхронизацию CSS анимации и видео, а также работоспособности во всех браузерах, то эта библиотека не решит вашу задачу. Но зато она прекрасно подходит для проектов, рассчитанных только на современные веб-клиенты. И даже не смотря на это ограничение большая часть данного материала всё ещё стоит того, чтобы её изучить.

Управление CSS анимациями через JavaScript

JavaScript — это клей между видео и CSS анимацией. Нет способа соединить анимацию с видео на чистом CSS. Анимация не начнётся, пока стиль не применён и CSS предоставляет несколько вариантов вызова дополнительных стилей (таких как :hover). Но для синхронизации анимации с видео нам понадобится ставить на паузу, останавливать, продолжать воспроизведение, переходить на середину видео и даже проигрывать анимации (вместе с видео) в обратную сторону.

Всё это можно реализовать через JS. Итак, первый шаг — получить CSS анимацию из таблицы стилей в JavaScript. Любая анимация делится на 2 части:
первая — keyframe и свойства, используемые для настройки поведения анимации, такие как длительность, количество повторений и направление;
вторая часть — это то, что будет запускать анимацию. Charlie.js нужны обе части в таблице стилей.

Первое, что нужно сделать, это написать функцию для поиска в таблицах стилей, которые загружены на страницу:

листинг кода

Функция findRules проходит через каждое выражение каждой таблицы стилей и возвращает список выражений, который совпадает с переданными в функцию matches. Чтобы получить все keyframe выражения мы передаём функцию в findRules , которая проверяет, является ли выражение keyframe-ом:

листинг кода

С этой точки зрения у нас уже есть keyframe в JavaScript, но нам всё ещё нужны другие стили анимаций, определяющие продолжительность, цикличность, направление и прочее.

Чтобы найти все эти свойства мы опять используем findRules чтобы проверить каждое выражение в каждой таблице стилей. В этот раз функция matches, которую мы передадим, проверит есть ли хоть в одном в выражении свойство animationName.

листинг кода

Функция animationsName нужна для обработки префиксов, поскольку свойство animationsName всё ещё требует префиксы в некоторых веб-браузерах. В результате функция выглядит вот так:

листинг кода

После того, как определяется необходимый префикс, имя кэшируется и используется при будущих его поисках.

Когда ключевые keyframe и стили анимаций собраны они передаются во helper class и хранятся в Charlie.js для дальнейшего использования.

листинг кода

Получаем информацию о синхронизации из data-атрибутов

Информация о времени прилагается к анимируемому элементу через data-атрибут. Итак, нам придётся перелопатить документ и выудить эту информацию. Любой элемент, который нужно анимировать помечается классом charlie, и это сильно облегчает на поиск:

листинг кода

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

requestAnimationFrame

Самым важным в Charlie.js является цикл, который запускается всякий раз, когда проигрывается видео. Этот цикл создаётся при помощи  requestAnimationFrame.

листинг кода

Функция requestAnimationFrame предназначена специально для оптимизации любого вида анимации, таких, как DOM манипуляции, прорисовка графики и WebGL. Это сложнее, чем просто setTimeout, но функция откалибрована для связи стадий анимации и компоновки их воедино, что делает результат более производительным. Также она является выгодным вариантом для энергосбережения на мобильных устройствах, так как полностью останавливает ход анимации, когда пользователь переключает вкладки.

Цикл начинает работать, когда запускается видео и останавливается вместе с видео. Charlie.js также нужно дать понять, видео остановилось или мы просто переключили куда-то на середину. Для каждого из этих событий требуется немного разный подход.

листинг кода

Пока видео проигрывается, цикл продолжается. Каждая итерация запускает следующий код:

листинг кода

Всё, что мы сделали на данный момент, было для поддержки этих нескольких строк кода. Переменная seconds — это просто значение video.currentTime, округлённое до одной десятой секунды. Значение bySeconds создано из информации о времени, взятой из HTML — просто это самый быстрый способ получить список анимаций, чтобы запустить его в данный момент времени. Массив running — это список анимаций, которые сейчас воспроизводятся. Цикл requestAnimationFrame действительно быстро действенный и запускается очень много раз в секунду, а Charlie.js поддерживает максимальную частоту обновления только раз в одну десятую секунды.

Итак, если какая-то анимация начинается на 2-й секунде, requestAnimationFrame попытается запустить её несколько раз, пока видео идёт следующую десятую долю секунды. Чтобы предотвратить повтор анимации в течении этой одной десятой секунды её добавляют в массив running, в котором находятся проигрываемые в данный момент анимации.

Чтобы запустить CSS анимацию, просто добавьте свойства анимации в стили элемента. Проще всего сделать это, добавив класс анимации в classList и это именно то, что делает метод start.

листинг кода

Имя анимации совпадает с именем класса, соответственно.

Пауза и продолжение анимации

Когда видео останавливается анимация должна останавливаться вместе с ним. Есть замечательный простой способ реализации, используя CSS анимации: мы просто задаём значению элемента animationPlayState статус paused.

листинг кода

Единственный хитрость состоит в том, чтобы отслеживать, какие анимации были приостановлены, чтобы можно было продолжить их, когда видео опять будет проигрываться:

листинг кода

Как запустить анимацию в середине

Что, если кто-то пролистает видео и перепрыгнет в середину анимации? Как запустить анимацию посередине видео? Свойство animationDelay — это именно то, что нам нужно. Обычно animationDelay устанавливают позитивное числовое значение. Если нужно, чтобы анимация началась через 3 секунды, после того, как её стили будут применены, то нужно установить animationDelay на 3s. Но если установить animationDelay отрицательное значение, то анимация перепрыгнет в середину. К примеру, если анимация длится 3 секунды, а нам нужно, чтобы анимация началась со второй секунды, зададим animationDelay значение -2s.

Каждый раз, когда пользователь ткнёт на середину видео, Charlie.js нужно остановить все анимации, которые проигрывались в данный момент, понять, что должно воспроизводится теперь, а потом присвоить подходящее animationDelay значение. Вот, собственно, хай-левел код:

листинг кода

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

листинг кода

timeModel — это список анимаций, отсортированный по времени окончания анимации. Это код ищет анимации, которые начинаются раньше текущего времени и заканчиваются после. Массив toStart содержит все анимации, которые должны начаться прямо сейчас.

Их значения передаются в хай-левел код, который считает и задаёт задержку в функции setDelay.

листинг кода

Параметр seconds — это текущее время видео. Предположим, что видео длится 30 секунда, а анимация начинается на 24-й секунде и длится 10 секунд. Если мы зададим задержку -6s, то анимация начнётся со своей 6-й секунды и продлится оставшиеся 4 секунды.

Для самостоятельного рассмотрения кода

Мы рассмотрели, как использовать requestAnimationFrame чтобы создать оптимизированный механизм для анимаций, как собрать keyframe-ы и стили из таблиц стилей, как запускать и останавливать анимации вместе с видео и даже как проигрывать CSS анимации с середины. Но в этой статье было пропущено немало промежуточного кода. Charlie.js — это только часть из сотен строк кода, но фрейворк opensource-ный и хорошо прокомментирован.

Вы, конечно, можете использовать этот ресурс, но с некоторыми оговорками:

  • Charlie.js был создан с образовательной целью. НЕ пытайтесь встроить его в продакт.
  • Кроссбраузерность для анимаций — это хорошо и Charlie.js старается быть дружественным ко всем браузерам. Однако он не был тщательно протестирован.
  • Он съедает производительность процессора даже если видео приостановлено (Что-то связанное с рендерингом CSS анимации)
  • Пользователь не должен двигать видео таймлайн, пока оно не на паузе. Иначе анимации будут накладываться друг на друга.
  • Charlie.js не отзывчив к изменениям частоты кадров. Поэтому если видео «заикается» или вы хотите снизить частоту кадров видео, анимация рассинхронизируется. Также нельзя проиграть видео в обратную сторону.
  • Анимации не начнётся, если текущая активная вкладка — это не вкладка с видео. Это происходит из-за requestAnimationFrame. Он не проигрывает видео, если вкладка с ним не активна. Это может запутать пользователей, которые переключаются между вкладками.

Какие-то из этих ограничений можно легко исправить, но Charlie.js был создан для очень ограниченного спектра действий.

Slide Background
ХОТИТЕ ЗАКАЗАТЬ САЙТ?
+7-4712-44-66-00

Самый простой способ начать работу с нами — позвонить.

ЗАПОЛНИТЬ АНКЕТУ

Ответьте на 8 простых вопросов и через 1-2 часа после получения анкеты мы подготовим предложение по решению вашей задачи

Контакты

Ждем вас уже сегодня

Вослользуйтесь удобным для вас способом связи или приезжайте к нам в офис, где вас ждет чашечка кофе

+7-4712-44-66-00
info@coda.website
Россия, г. Курск
ул. Литовская 12а