Вращающий слайдер на jQuery и CSS3
В данном уроке мы создадим ассиметричный слайдер с небольшим поворотом изображений: когда выполняется скольжение изображений, они слегка поворачиваются, а анимация для каждой картинки выполняется с небольшой задержкой. Необычная форма слайдера создается размещением элементов и использованием толстой рамки. Слайдер имеет опцию автопроигрывания и функционал работы с колесиком мыши.
В слайдере используются плагины jQuery 2D Transformation для вращения изображений и Mousewheel для управления мышью.
Разметка HTML
Все элементы слайдера содержатся в контейнере с классом “rm_wrapper”:
<div class="rm_wrapper"> ... </div>
Внутри содержится контейнер для списка элементов слайдера, маски и углы, заголовок и скрытые элементы div
, которые содержат наборы изображений:
<div id="rm_container" class="rm_container"> <ul> <li data-images="rm_container_1" data-rotation="-15"><img src="/images/1.jpg"/></li> <li data-images="rm_container_2" data-rotation="-5"><img src="/images/2.jpg"/></li> <li data-images="rm_container_3" data-rotation="5"><img src="/images/3.jpg"/></li> <li data-images="rm_container_4" data-rotation="15"><img src="/images/4.jpg"/></li> </ul> <div id="rm_mask_left" class="rm_mask_left"></div> <div id="rm_mask_right" class="rm_mask_right"></div> <div id="rm_corner_left" class="rm_corner_left"></div> <div id="rm_corner_right" class="rm_corner_right"></div> <h2>Взрыв моды 2012</h2> <div style="display:none;"> <div id="rm_container_1"> <img src="/images/1.jpg"/> <img src="/images/5.jpg"/> <img src="/images/6.jpg"/> <img src="/images/7.jpg"/> </div> <div id="rm_container_2"> <img src="/images/2.jpg"/> <img src="/images/8.jpg"/> <img src="/images/9.jpg"/> <img src="/images/10.jpg"/> </div> <div id="rm_container_3"> <img src="/images/3.jpg"/> <img src="/images/11.jpg"/> <img src="/images/12.jpg"/> <img src="/images/13.jpg"/> </div> <div id="rm_container_4"> <img src="/images/4.jpg"/> <img src="/images/14.jpg"/> <img src="/images/15.jpg"/> <img src="/images/16.jpg"/> </div> </div> </div>
В первом неупорядоченном списке содержатся четыре элемента, каждый имеет атрибуты для указания набора изображений и угла поворота. Атрибуты используются для получения следующего изображения и установки его в нужное положение.
Элементы div
масок и углов позиционируются абсолютно поверх слайдера и немного повернуты, чтобы прикрывать некоторые области. Так как мы используем одинаковый цвет фона для данных элементов и всей страницы, то создается иллюзия, что изображения имеют определённую форму.
Затем следуют элементы навигации и управления автопроигрыванием:
<div class="rm_nav"> <a id="rm_next" href="#" class="rm_next"></a> <a id="rm_prev" href="#" class="rm_prev"></a> </div> <div class="rm_controls"> <a id="rm_play" href="#" class="rm_play">Запустить</a> <a id="rm_pause" href="#" class="rm_pause">Остановить</a> </div>
CSS
Сначала осуществляется сброс и определяются свойства для страницы. (Если вы захотите поменять цвет фона страницы, то нужно будет изменять цвета фона и рамок некоторых элементов слайдера):
@import url('reset.css'); body{ background:#f0f0f0; color:#000; font-family: 'PT Sans Narrow', Arial, sans-serif; font-size:16px; } a{ color:#000; text-decoration:none; } h1{ padding:10px; margin:20px; font-size:40px; text-transform:uppercase; text-shadow:0px 0px 1px #fff; color:#333; background:transparent url(../images/line.png) repeat-x bottom left; }
Основной контейнер имеет следующий стиль:
.rm_wrapper{ width:1160px; margin:0 auto; position:relative; }
Контейнер для слайдера скрывает всё выступающее за его пределы:
.rm_container{ width:1050px; overflow:hidden; position:relative; height:530px; margin:0 auto; }
Заголовок имеет следующий стиль:
.rm_container h2{ background:transparent url(../images/lines.png) repeat top left; padding:10px 30px; position:absolute; bottom:170px; right:0px; color:#000; font-size:36px; text-transform:uppercase; text-shadow:1px 0px 1px #fff; }
Ширина неупорядоченно списка будет больше ширины контейнера, так как все элементы списка будут плавающими со смещением влево, чтобы располагаться рядом друг с другом:
.rm_container ul{ width:1170px; }
Задавая отрицательное левое смещение и толстую рамку для элементов списка, мы добиваемся перекрытия изображений и обрезки правой части для создания ассиметричной формы при последующем вращении. Цвет рамки должен быть таким же, как и цвет фона страницы:
.rm_container ul li{ float:left; margin-left:-80px; position:relative; overflow:hidden; width:310px; height:465px; border:30px solid #f0f0f0; border-width:50px 30px 0px 30px; background-color:#f0f0f0; }
Изображения позиционируются абсолютно:
.rm_container ul li img{ position:absolute; top:0px; left:0px; }
Затем мы задаем стиль элементов маски и углов. Они позиционируются абсолютно и имеют цвет фона. Вращая их, мы получаем особую форму изображений:
.rm_mask_right, .rm_mask_left{ position: absolute; height: 110px; background: #f0f0f0; width: 530px; bottom: -30px; left: 0px; -moz-transform:rotate(-3deg); -webkit-transform:rotate(-3deg); transform:rotate(-3deg); } .rm_mask_right{ left:auto; right:0px; -moz-transform:rotate(3deg); -webkit-transform:rotate(3deg); transform:rotate(3deg); } .rm_corner_right, .rm_corner_left{ background: #f0f0f0; position:absolute; width:200px; height:100px; bottom:0px; left:-65px; -moz-transform:rotate(45deg); -webkit-transform:rotate(45deg); transform:rotate(45deg); } .rm_corner_right{ left:auto; right:-65px; -moz-transform:rotate(-45deg); -webkit-transform:rotate(-45deg); transform:rotate(-45deg); }
Элементы навигации размещаются справа и слева от основного контейнера:
.rm_nav a{ position:absolute; top:200px; width:38px; height:87px; cursor:pointer; opacity:0.7; } .rm_nav a:hover{ opacity:1.0; } .rm_nav a.rm_next{ background:transparent url(../images/next.png) no-repeat top left; right:0px; } .rm_nav a.rm_prev{ background:transparent url(../images/prev.png) no-repeat top left; left:0px; }
Элементы управления автопроигрыванием размещаются слева вверху основного контейнера:
.rm_controls{ position:absolute; top:0px; left:0px; height:20px; } .rm_controls a{ cursor:pointer; opacity:0.7; padding-left:24px; font-size:16px; text-transform:uppercase; height:20px; float:left; line-height:20px; } .rm_controls a:hover{ opacity:1.0; } .rm_controls a.rm_play{ display:none; background:transparent url(../images/play.png) no-repeat center left; } .rm_controls a.rm_pause{ background:transparent url(../images/pause.png) no-repeat center left; }
JavaScript
Идея функционирования слайдера заключается в добавлении следующего изображения над текущим с небольшим изменением угла поворота. Затем происходит анимация вращения и появляется новое изображение.
Начнем с кэширования некоторых элементов и определения типа браузера, чтобы модифицировать функционал нашего слайдера:
//Наши 4 пункта var $listItems = $('#rm_container > ul > li'), totalItems = $listItems.length, //Управление $rm_next = $('#rm_next'), $rm_prev = $('#rm_prev'), $rm_play = $('#rm_play'), $rm_pause = $('#rm_pause'), //Маски и углы для слайдера $rm_mask_left = $('#rm_mask_left'), $rm_mask_right = $('#rm_mask_right'), $rm_corner_left = $('#rm_corner_left'), $rm_corner_right= $('#rm_corner_right'), //Проверка версии браузера <= IE8 ieLte8 = ($.browser.msie && parseInt($.browser.version) <= 8),
Затем мы определяем основную функцию:
RotateImageMenu = (function() { ... })(); RotateImageMenu.init();
И создаем ее содержание:
//Разница между анимациями пунктов var timeDiff = 300, //Время между анимациями для слайдшоу slideshowTime = 3000, slideshowInterval, //Флаг вращения изображения isRotating = false, //Счетчик изображений в итерации слайдшоу completed = 0, /* Все изображения имеют ширину 310 px и высоту 465 px. Данные параметры надо вычислять автоматически, если нужно использовать изображения разных размеров. Мы устанавливаем вращение оригинала вокруг центра с координатами x = ширина/2 и y = высота*2 */ origin = ['155px', '930px'], init = function() { configure(); initEventsHandler(); startSlideshow(); }, //Инициализация некоторых событий initEventsHandler = function() { /* Стрелки "следующий" и "предыдущий": останавливаем слайдшоу, если оно активно и вращаем каждое изображение. 1 поворот вправо, -1 поворот влево */ $rm_next.bind('click', function(e) { stopSlideshow(); rotateImages(1); return false; }); $rm_prev.bind('click', function(e) { stopSlideshow(); rotateImages(-1); return false; }); /* Остановка и запуск слайдшоу */ $rm_play.bind('click', function(e) { startSlideshow(); return false; }); $rm_pause.bind('click', function(e) { stopSlideshow(); return false; }); /* Добавляем события для мыши и кнопок влево/вправо */ $(document).bind('mousewheel', function(e, delta) { if(delta > 0) { stopSlideshow(); rotateImages(0); } else { stopSlideshow(); rotateImages(1); } return false; }).keydown(function(e){ switch(e.which){ case 37: stopSlideshow(); rotateImages(0); break; case 39: stopSlideshow(); rotateImages(1); break; } }); }, /* Вращаем каждое изображение. Устанавливаем задержку между анимациями пунктов. */ rotateImages = function(dir) { //Если анимация в процессе выполнения. if(isRotating) return false; isRotating = true; $listItems.each(function(i) { var $item = $(this), /* Вычисление задержки. Если вращение выполняется вправо, то первый пункт для вращения будет анимироваться первым, иначе - последним. */ interval = (dir === 1) ? i * timeDiff : (totalItems - 1 - i) * timeDiff; setTimeout(function() { //Изображения, связанные с данным пунтком var $otherImages = $('#' + $item.data('images')).children('img'), totalOtherImages = $otherImages.length; //Текущее изображение $img = $item.children('img:last'), //Получаем данные current current = $item.data('current'); //Проверяем выход за пределы списка if(current > totalOtherImages - 1) current = 0; else if(current < 0) current = totalOtherImages - 1; //Следующее изображение для вывода и его начальное вращение (зависит от направления) var otherRotation = (dir === 1) ? '-30deg' : '30deg', $other = $otherImages.eq(current).clone(); //Для IE <= 8 вращений не будет, но будет затухание ... //Лучше, чем ничего :) if(!ieLte8) $other.css({ rotate : otherRotation, origin : origin }); (dir === 1) ? ++current : --current; //Вставляем следующее изображение для <li> $item.data('current', current).prepend($other); //Окончательное вращение для текущего изображения var rotateTo = (dir === 1) ? '80deg' : '-80deg'; if(!ieLte8) { $img.animate({ rotate : rotateTo }, 1200, function(){ $(this).remove(); ++completed; if(completed === 4) { completed = 0; isRotating = false; } }); $other.animate({ rotate : '0deg' }, 600); } else { $img.fadeOut(1200, function(){ $(this).remove(); ++completed; if(completed === 4) { completed = 0; isRotating = false; } }); } }, interval ); }); }, //Устанавливаем начальное вращение configure = function() { if($.browser.msie && !ieLte8) rotateMaskCorners(); else if(ieLte8) hideMaskCorners(); $listItems.each(function(i) { //Начальное значение current равно 1, //так как мы уже показали первое изображение var $item = $(this).data('current', 1); if(!ieLte8) $item.transform({rotate: $item.data('rotation') + 'deg'}) .find('img') .transform({origin: origin}); }); }, //Вращаем маски и углы rotateMaskCorners = function() { $rm_mask_left.transform({rotate: '-3deg'}); $rm_mask_right.transform({rotate: '3deg'}); $rm_corner_left.transform({rotate: '45deg'}); $rm_corner_right.transform({rotate: '-45deg'}); }, //Скрываем маски и углы hideMaskCorners = function() { $rm_mask_left.hide(); $rm_mask_right.hide(); $rm_corner_left.hide(); $rm_corner_right.hide(); }, startSlideshow = function() { clearInterval(slideshowInterval); rotateImages(1); slideshowInterval = setInterval(function() { rotateImages(1); }, slideshowTime); //Выводим кнопку паузы и скрываем кнопку запуска $rm_play.hide(); $rm_pause.show(); }, stopSlideshow = function() { clearInterval(slideshowInterval); //Выводим кнопку запуска и скрываем кнопку паузы $rm_pause.hide(); $rm_play.show(); }; return {init : init};
Для старых браузеров функционирование слайдера будет отличаться - используется простое затухание для смены изображений.
Источник: http://feedproxy.google.com/~r/ruseller/CdHX/~3/igLwBy4kP3w/lessons.php
Дайджест новых статей по интернет-маркетингу на ваш email
Новые статьи и публикации
- 2024-11-26 » Капитан грузового судна, или Как начать использовать Docker в своих проектах
- 2024-11-26 » Обеспечение безопасности ваших веб-приложений с помощью PHP OOP и PDO
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-22 » Ошибки в Яндекс Вебмастере: как найти и исправить
- 2024-11-15 » Перенос сайта на WordPress с одного домена на другой
- 2024-11-08 » OSPanel 6: быстрый старт
- 2024-11-08 » Как установить PhpMyAdmin в Open Server Panel
- 2024-09-30 » Как быстро запустить Laravel на Windows
- 2024-09-25 » Next.js
- 2024-09-05 » OpenAI рассказал, как запретить ChatGPT использовать содержимое сайта для обучения
- 2024-08-28 » Чек-лист: как увеличить конверсию интернет-магазина на примере спортпита
- 2024-08-01 » WebSocket
- 2024-07-26 » Интеграция с Яндекс Еда
- 2024-07-26 » Интеграция с Эквайринг
- 2024-07-26 » Интеграция с СДЕК
- 2024-07-26 » Интеграция с Битрикс-24
- 2024-07-26 » Интеграция с Travelline
- 2024-07-26 » Интеграция с Iiko
- 2024-07-26 » Интеграция с Delivery Club
- 2024-07-26 » Интеграция с CRM
- 2024-07-26 » Интеграция с 1C-Бухгалтерия
- 2024-07-24 » Что такое сторителлинг: техники и примеры
- 2024-07-17 » Ошибка 404: что это такое и как ее использовать для бизнеса
- 2024-07-03 » Размещайте прайс-листы на FarPost.ru и продавайте товары быстро и выгодно
- 2024-07-01 » Профилирование кода в PHP
- 2024-06-28 » Изучаем ABC/XYZ-анализ: что это такое и какие решения с помощью него принимают
- 2024-06-17 » Зачем вам знать потребности клиента
- 2024-06-11 » Что нового в работе Яндекс Метрики: полный обзор обновления
- 2024-06-11 » Поведенческие факторы ранжирования в Яндексе
- 2024-06-11 » Скорость загрузки сайта: почему это важно и как влияет на ранжирование
Всегда храни верность своему начальнику - следующий, может быть еще хуже... |
Мы создаем сайты, которые работают! Профессионально обслуживаем и продвигаем их , а также по всей России и ближнему зарубежью с 2006 года!
Как мы работаем
Заявка
Позвоните или оставьте заявку на сайте.
Консультация
Обсуждаем что именно Вам нужно и помогаем определить как это лучше сделать!
Договор
Заключаем договор на оказание услуг, в котором прописаны условия и обязанности обеих сторон.
Выполнение работ
Непосредственно оказание требующихся услуг и работ по вашему заданию.
Поддержка
Сдача выполненых работ, последующие корректировки и поддержка при необходимости.