
Предисловие
Несколько недель назад в просторах интернета я увидел очень заинтересовавшую меня вещь — iOS иконки на CSS3 полностью без картинок. Первое что подумал — «Я тоже так могу»! А спустя еще 5 минут для себя четко решил — «challenge accepted». Но чтоб не повторяться я решил немножко усложнить задачу — сделать не только иконки, но и сам девайс.
Постановка задачи
Итак, в тот-же день я решил сделать iPhone4 на CSS3 абсолютно без картинок, base64, canvas или SVG и добавить еще некоторую изюминку — интерактивные возможности:
— включение/выключение;
— блокировка при включении и разблокировка как в реальном iPhone;
— анимация «slide to unlock» текста на экране блокировки;
Используемые технологии
CSS3
Интересные и необходимые технологии CSS3, которые и обрисовали всю картину без графики:
— border-radius для скругления уголков практически всех составляющих элементов устройства.
— box-shadow для создания как внешних так и внутренних теней элементов.
— background: linear-gradient и background: radial-gradient — создание большинства цветных заливок иконок и бликов.
— background-size — для создания полосатого фона у иконок Message и Phone;
— transform: rotate, skew, scale — трансформирование некоторых составляющих иконок, для создания максимально схожих к идеалу картинок;
— before и after псевдоэлементы — для минимизации HTML кода;
— :nth-child(n) — для выборки n-го элемента в динамике и некоторых иконках типа App Store и iTunes, содержащих одинаковые внутренние элементы c небольшим отличием примерно в 1-м или двух свойствах.
jQuery + jQuery UI
Из этой технологии не использовалось практически ничего уникального. Набор animate() функции для анимации «slide to unlock», вылета иконок и убирания панелей блокировки при разблорировке, draggable эффекта для слайдера при разблокировке.
Стиль написания самого скрипта унаследован у Html5BoilerPlate.
HTML
В HTML я не стал использовать кастомные теги, хоть это и позволено, а просто использовал в основном div, hr, b, и списки.
Куски кода
HTML cтруктура iPhone
<div class="iphone"> <div class="iphone_light_gradient"></div> <!-- блик на iPhone --> <div class="iphone_power_button" id="iphone_power_button"></div> <!-- кнопка вкл./выкл. --> <div class="iphone_voice_toogle"></div> <!-- переключатель на беззвучный режим --> <div class="iphone_voice_plus"></div> <!-- кнопка "+" --> <div class="iphone_voice_minus"></div> <!-- кнопка "-" --> <div class="iphone_camera"></div> <!-- фронтальная камера --> <div class="iphone_dynamic"><span></span><!-- куча span для точек на динамике --><span></span></div> <!-- динамик --> <div class="iphone_black_bg"></div> <!-- черная подложка передней части устройства --> <div class="iphone_display" > <!-- сам дисплей со всеми внутренностями --> <div class="iphone_headline" id="iphone_headline"> <!-- верхная черная полоса экрана --> <div class="iphone_net"></div> <!-- Индикатор сети --> <div class="iphone_net_title">tjrus</div> <!-- Имя сети --> <div class="iphone_wi-fi"><div class="hack"></div></div> <!-- Индикатор wi-fi --> <div class="iphone_clock" id="iphone_headline_clock">00:00</div> <!-- часы --> <div class="iphone_lock"></div> <!-- замок --> <div class="iphone_battery"></div> <!-- индикатор батареи --> </div> <div class="iphone_header" id="iphone_lock_header"> <!-- верхняя панель заблокированного экрана --> <div class="iphone_time" id="iphone_lock_time">0<span>:</span>00</div> <!-- часы --> <div class="iphone_date" id="iphone_lock_date"></div> <!-- дата --> </div> <div class="iphone_footer" id="iphone_lock_footer"> <!-- нижняя часть заблокированного экрана --> <div class="iphone_unlock" id="iphone_unlock"> <!-- область "slide to unlock" --> <div class="iphone_slider" id="iphone_slider"></div> <!-- слайдер (ползунок) --> <div class="iphone_slide2unlock" id="iphone_slide2unlock">slide to unlock</div> </div> </div> <div class="iphone_icons_containter" id="iphone_icons_containter"> <!-- контейнер иконок --> <div class="icon"></div> <!-- пример контейнера иконки ( их таких 16-ть подряд) --> </div> <div class="iphone_dock" id="iphone_dock"> <!-- док --> <div class="icon"></div> <!-- пример контейнера иконки ( их в доке 4 штучки ) --> </div> </div> <div class="iphone_home" id="iphone_home_button"></div> <!-- кнопка "домой" ("home button") --> </div>
CSS3 интересные части
(Полный CSS код приводить было бы не уместно, так как там всего-то 3395 строчки кода)
Иконки
Все иконки заключаются в контейнеры с классом «icon», дабы их можно было безболезненно переставлять местами в коде по надобности и чтоб задать сразу им обрамительный единый стиль с тенью и названием.
.icon { width: 56px; height: 56px; border-radius: 10px; box-shadow: rgba(0,0,0,0.5) 0 1px 2px; margin-bottom: 30px; position: absolute; } .icon span { /* содержит название иконки */ display: block; text-align: center; font: bold 11px/15px "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; color: #fff; text-shadow: rgba(0,0,0,0.3) 1px 2px 1px; text-transform: capitalize; position: absolute; top: 58px; left: -10px; width: 76px; }
так как иконки у нас располагаются по матрице, то их удобно позиционировать таким вот простым способом:
.icon:nth-child(4n + 1) { left:17px; } .icon:nth-child(4n + 2) { left:92px; } .icon:nth-child(4n + 3) { left:168px; } .icon:nth-child(4n + 4) { left:243px; } .icon:nth-child(-n + 16) { top: 258px; } .icon:nth-child(-n + 12) { top: 172px; } .icon:nth-child(-n + 8) { top: 86px; } .icon:nth-child(-n + 4) { top: 0; }
для дока немного другой случай позиционирования:
.iphone_dock .icon:nth-child(1) { margin-left:7px; margin-right: 19px; } .iphone_dock .icon:nth-child(2) { margin-right: 20px; } .iphone_dock .icon:nth-child(3) { margin-right: 19px; }
Тем кому интересен полный код иконок — его лучше смотреть в исходном коде на самой странице, ибо код очень велик.
jQuery интересные части
Как я уже и говорил — взял стиль написания скрипта у html5BoilerPlate. Все настройки, возможности и состояния iPhone описаны в одном объекте. Структура объекта iphone:
iphone = { slide_started : false, // начался ли слайд разблокировки letter_animate_time : 50, // время анимации буквы panels_animate_time : 400, // время анимации исчезновения панелей при разблокировке status : 'lock', // текущий статус устройства. Возможные статусы: "lock", "unlock", "off" iconsDefaultPosition : {}, // содержит значения позиции иконок при разблокированном iPhone iconsOutPosition : {}, // содержит значения позиции иконок при заблокированном iPhone init : function(){}, // инициализация онкликов, слайдов, перечсета позиции иконок, начала анимации текста endSlide : function(){}, // функция обработки окончания слайда при разблокировке turnOn : function(){}, // включение iPhone turnOff : function(){}, // выключение iPhone lock : function(){}, // блокирование iPhone unlock : function(){}, // разблокировка iPhone showIcons : function(){}, // анимация показа оконок при разблокировке hideIcons : function(){}, // уход иконок за экран без анимации animateHideIcons : function(){}, // анимацая ухода иконок за экран prepareIcons : function(){}, // функция собирает дефолтные значения положения иконок, и устанавливает их за экран в заблокированный режим timeUpdate : function(){}, // обновление время устройства на заблокированном экране, в верхней линии и иконке stopTextAnimate : function(){}, // остановка текстовой анимации startTextAnimate : function(){}, // старт текстовой анимации prepareTextAnimate : function () {}, // подготовка текста "slide to unlock" к анимации animateLetters : function() {}, // запуск цикла анимации букв в "slide to unlock" ua : function() {}, // функция определения типа браузера (user agent) }
Обработка процесса «Slide to unlock»
$("#iphone_slider").draggable({ containment: 'parent', axis: 'x', start: function(event, ui) { $(document).mousemove(function(){ if(iphone.slide_started){ var left = $("#iphone_slider").css('left').substring(0, $("#iphone_slider").css('left').length - 2); var width = $('#iphone_unlock').width() - $('#iphone_slider').width(); var opacity_k = (width - left*3) / (width); $('#iphone_slide2unlock').css({'opacity': opacity_k}, TIME/2); // делаем текст прозрачнее по мере процесса слайда ползунка } }); }, stop: function(event, ui){ $(document).unbind('mousemove'); } }); $("#iphone_slider").mousedown(function(){ iphone.slide_started = true; }); $(document).mouseup(function(){ if (iphone.slide_started){ iphone.endSlide(); // в этой функции определяем достаточно ли дотянули мы слайдер для того чтоб разблокировать, или же возвращаем слайдер в исходную позицию. iphone.slide_started = false; } });
Что получилось
В результате страница отлично демонстрирует многие, но далеко не все возмoжности CSS3. К большому моему сожалению на веб-сайтах весь такой код использовать нельзя из-за сложного CSS3 (анимация вылета иконок сильно тормозит в браузерах).
Кроссбраузерность
Увы этот пункт наверное самый печальный. iPhone4 на CSS3 отлично работает в WebKit браузерах Safari и Chrome под Mac OS X (в Windows возможно неправильное отображение иконки Phone), так же правильно отображается в последних Firefox и Opera. Для iOS устройств пришлоcь выключить анимацию «slide to unlock», которая очень сильно замедляла страницу в браузере устройства. Что касается Internet Explorer — приношу ему свои извинения.
Демо
сама страница — iPhone4 на CSS3
стили — iphone.css
скрипт — iphone.js
