Статьи

Объяснение последовательности заголовков WDS: HTML5 и CSS3 в действии

Я только что вернулся из Web Directions South в Сиднее, где я увидел несколько вдохновляющих ораторов, выходящих на сцену и смешанных с кучей других интернет-ориентированных личностей. Но самое вдохновляющее, что я увидел, произошло в первые десять минут конференции: вступительная последовательность Кэмерона Адамса. На первый взгляд, это просто анимация, раскрывающая имена всех ораторов с некоторыми классными эффектами, сыгранными в ремикс саундтрека к фильму « Начало» . Затем вы узнаете, что он создан с использованием HTML5, CSS3 и JavaScript в браузере.

Начните с проверки ; вам придется просматривать его с помощью Chrome. Чтобы он работал правильно, вам нужно настроить разрешение экрана на 1024 на 768, загрузить страницу, переключиться в полноэкранный режим, а затем обновить страницу, чтобы увидеть ее с самого начала в правильном разрешении.

Хотя он основан на саундтреке из Inception , демо Кэмерон не опирается на набор персонажей, объясняющих нам в течение трех часов, что происходит. По этой причине я решил погрузиться в источник, чтобы увидеть магию за кулисами. Демонстрация состоит из более чем 800 строк CSS и 2400 строк JavaScript (не считая jQuery и нескольких обезьяньих патчей для добавления поддержки CSS3), поэтому я просто расскажу о поверхности, чтобы объяснить некоторые эффекты кулера. , Если вас больше интересует обзор верхнего уровня того, что в нем было задействовано (и некоторые странные ошибки, встречающиеся на этом пути), посмотрите сообщение в блоге Кэмерона .

Музыка для ваших ушей

Первое, что вы заметите при просмотре исходного кода демонстрационной страницы, это то, что внутри тегов <body> есть только один HTML-элемент — audio элемент:

  <audio id = "music" src = " Music.mp3 " oncanplaythrough = "start ();"  преднагрузки = "Авто"> </ аудио> 

Это, конечно, новый элемент HTML5 для встроенного аудио в браузере.

Ключевым моментом здесь является атрибут oncanplaythrough . Как и любой атрибут чего-либо, он относится к событию, запускаемому в браузере. В этом случае событие canplaythrough срабатывает, когда элемент загружает достаточно мультимедийного файла, чтобы иметь возможность воспроизвести его до конца без буферизации. Кэмерон использует его для вызова метода start() в своем JavaScript, чтобы запустить анимацию.

Сроки это все

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

Как это возможно? JavaScript-код Кэмерона начинается с большого массива объектов, который называется TIME_CODE . Каждый объект в массиве содержит временной код и имя функции. Временной код представляет собой либо число (в секундах от начала дорожки), либо строку типа "+4" , что означает «4 секунды после последнего временного кода». Когда вы просматриваете массив, вы увидите см. несколько временных кодов, указанных как кратные константе BEAT . Эта константа является точным интервалом между нотами фортепиано в первые несколько секунд музыки: 1,79 секунды.

Метод start() , который запускается, как только звук готов к воспроизведению (как мы видели ранее), выглядит следующим образом:

 function start() { $("body").unbind("click"); stageWidth = $(window).width(); stageHeight = $(window).height(); startDate = new Date(); var music = document.getElementById("music"); music.play(); setInterval(tick, 10); } 

Самые важные строки — последние два. Сначала он начинает играть музыку; затем он устанавливает интервал для запуска tick метода каждые десять миллисекунд. Метод tick является краеугольным камнем всего скрипта:

 function tick() { var music = document.getElementById("music"); if (TIME_CODE.length > 0) { var time = 0; if (typeof TIME_CODE[0].time == "string") { time = lastTime + parseFloat(TIME_CODE[0].time.replace(/+/, "")); } else { time = TIME_CODE[0].time; } if (music.currentTime >= time) { TIME_CODE[0].func(); lastTime = time; TIME_CODE.splice(0, 1); } } } 

Это все еще довольно просто: код захватывает первый элемент в массиве TIME_CODE ; затем проверяет, является ли свойство time этого объекта абсолютным или относительным (то есть, является ли оно строкой или числом). Если он относительный, код добавляет его в переменную lastTime для текущего временного кода. Затем он получает currentTime время музыки; это встроенное свойство audio HTML5. Если тайм-код, который мы ждем, прибыл, код запускает функцию, связанную с ним, устанавливает lastTime , а затем lastTime этот первый элемент массива TIME_CODE используя splice .

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

Переходы, трансформации и анимации, о мой!

Первая функция в TIME_CODEpresents() , но я пропущу большую часть этой функции, потому что все, что она на самом деле делает, это перебирает все буквы строки «Представления веб-направлений: юг 2010» и затемняет их. Интересно то, что затухание происходит в CSS, а не в JavaScript. Код JavaScript просто устанавливает opacity каждой буквы либо на 0,9, либо на 0, что обычно выглядело бы, как буквы включались или выключались. Однако в CSS вы увидите такие правила:

 -webkit-transition: all 3s ease-in; 

Это означает, что всякий раз, когда изменяется любое свойство целевого элемента (будь то с помощью JavaScript или в самом CSS с измененным селектором псевдокласса), оно будет анимировано в течение трех секунд с помощью функции синхронизации ease-in времени. Чтобы узнать больше о функциях синхронизации и других доступных параметрах, ознакомьтесь со спецификацией W3C в модуле перехода CSS . Конечным результатом является то, что каждая буква будет плавно исчезать.

Теперь давайте посмотрим на более интересный эффект: те пульсирующие круги, о которых я говорил ранее. Каждый круг на самом деле является div с border-radius половине его размера. Те световые импульсы, которые исходят из каждого круга, являются просто идентичными div с применением некоторой CSS-анимации. Вот соответствующий CSS:

 ._1pulse { position: absolute; background: -webkit-gradient(radial, 50% 50%, 0, 50% 50%, 30, from(rgba(255,255,255,0)), to(rgba(255,255,255,1))); opacity: 0.4; -webkit-animation-name: _1pulseAnim; -webkit-animation-duration: 1.85s; -webkit-animation-timing-function: ease-out; } @-webkit-keyframes _1pulseAnim { 0% {opacity: 0.4; -webkit-transform: scale(1)} 100% {opacity: 0; -webkit-transform: scale(5)} } 

Этот код содержит две отдельные части магии CSS3. Прежде всего, импульс имеет фоновый радиальный градиент, примененный с -webkit-gradient . Второе, и самое интересное, это анимация. Для CSS3-анимации необходимо сначала настроить несколько ключевых кадров с @keyframes объявления @keyframes (или в этом случае @-webkit-keyframes ). Набор ключевых кадров получает имя ( _1pulseAnim ), на которое затем можно ссылаться из правила CSS. Каждый ключевой кадр имеет селектор: процент, который сообщает браузеру, в какой точке анимации находится ключевой кадр. В этом очень простом случае Кэмерон имеет только два ключевых кадра: один для начального состояния (0%) и один для конечного состояния (100%). Только два свойства анимированы: opacity и scale . Затем эти ключевые кадры присваиваются анимации данного элемента путем включения их в объявление -webkit-animation-name , как в приведенном выше коде.

Конечный результат заключается в том, что, когда импульсный div добавляется к документу, анимация запускается. Он масштабируется до пятикратного размера центрального круга, а затем исчезает.

Для его следующего трюка …

На этой странице есть множество других анимаций: сеть линий, простирающихся между этими кругами, за которыми следует прокручивающаяся стена букв, которая останавливается, чтобы выделить имена других докладчиков. У меня нет места, чтобы посмотреть, как это делается, но вы можете сами погрузиться в код, если вам интересно. Однако я хочу кратко коснуться того, что для меня является наиболее впечатляющей анимацией: белые прямоугольники, которые вращаются вокруг экрана, чтобы показать имена позади них. Хотите верьте, хотите нет, почти вся эта анимация выполняется путем добавления одного класса к одному div . Кэмерон сначала создает все имена, а затем устанавливает тайм-аут для постепенного исчезновения каждого из них в определенный момент времени. Затем он берет гигантский div содержащий все прямоугольники со скругленными углами, и добавляет класс fly :

 $("#_13blocks").addClass("fly") 

Эта безобидная строка кода запускает следующую анимацию CSS:

 #_13blocks.fly { -webkit-animation-name: fly, flyOrigin; -webkit-animation-duration: 19.7s, 19.7s; -webkit-animation-timing-function: ease-in-out, ease-in-out; -webkit-animation-fill-mode: forwards, forwards; } @-webkit-keyframes fly { 0% {-webkit-transform: rotate(0deg) scale(1);} 8.3% {-webkit-transform: rotate(-90deg) scale(3);} 16.6% {-webkit-transform: rotate(-180deg) scale(4.3);} 24.9% {-webkit-transform: rotate(-270deg) scale(5.6);} 33.2% {-webkit-transform: rotate(-360deg) scale(7.5);} 41.5% {-webkit-transform: rotate(-450deg) scale(10);} 49.8% {-webkit-transform: rotate(-540deg) scale(13);} 51.5% {-webkit-transform: rotate(-540deg) scale(13);} 58.1% {-webkit-transform: rotate(-630deg) scale(13);} 59.6% {-webkit-transform: rotate(-630deg) scale(13);} 66.4% {-webkit-transform: rotate(-720deg) scale(13);} 67.9% {-webkit-transform: rotate(-720deg) scale(13);} 74.7% {-webkit-transform: rotate(-810deg) scale(13);} 76.2% {-webkit-transform: rotate(-810deg) scale(13);} 95.0% {-webkit-transform: rotate(-990deg) scale(1);} 96.0% {-webkit-transform: rotate(-990deg) scale(1); -webkit-animation-timing-function: ease-in;} 100% {-webkit-transform: rotate(-990deg) scale(15);} } 

Каждый ключевой кадр определяет rotation и scale (большинство из которых очень велики, чтобы div несколько раз больше, чем область просмотра браузера). Результат: div облетает экран, останавливаясь с белой областью, выровненной для отображения строки текста. Каждая строка исчезнет в этот момент, благодаря тайм-аутам, указанным ранее в JavaScript. Затем контейнер снова поворачивается, чтобы отобразить следующее имя. Функция хронометража облегчает ease-in-out делает анимацию гладкой и естественной, с небольшим количеством отказов. Общий эффект — потрясающая демонстрация силы CSS3-анимации.

Ненавистники пусть ненавидят

Скептики из вас теперь будут кричать: «Это работает только с определенным разрешением в определенном браузере и использует массу префиксов поставщиков! Это бесполезно в реальном мире! »Дело в том, что он работает в контексте, для которого он был разработан: он воспроизводился в браузере, проецировался на экран и уносил нас всех. Это даже близко не самый простой способ создания этой анимации, но он служит для того, чтобы показать нам, куда мы идем, и что не за горами для веб-разработчиков. С IE9, поддерживающим ряд функций CSS3 (хотя, к сожалению, не анимации, которые создали эту демонстрацию), войны браузеров возобновились, за исключением того, что на этот раз они ведут борьбу за стандарты.

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

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