Слайдшоу с 3D эффектами

Разметка HTML

У нас будет использоваться основной контейнер с классом jms-slideshow. В нем будут размещаться несколько элементов с классом step. Данный элемент соответствует одному слайду. Каждый слайд получает класс data-color для формирования цвета фона и несколько атрибутов data для плагина jmpress.js. В нашем проекте используются опции для определения позиции и вращения слайда в 3D пространстве:

Код
<section id="jms-slideshow" class="jms-slideshow">
   
  <div class="step" data-color="color-1">
  <div class="jms-content">
  <h3>Заголовок</h3>
  <p>Текст слайда</p>
  <a class="jms-link" href="#">Читаем дальше</a>
  </div>
  <img src="images/1.png" />
  </div>
   
  <div class="step" data-color="color-2" data-y="500" data-scale="0.4" data-rotate-x="30">
  <!-- ... -->
  </div>
   
  <!-- ... -->
   
</section>


CSS

Так как слайдшоу будет адаптивным, то основной контейнер будет иметь ширину, установленную в процентах, с ограничением максимального и минимального значений:

Код
.jms-slideshow {
  position: relative;
  width: 80%;
  max-width: 1400px;
  min-width: 640px;
  margin: 20px auto;
  height: 460px;
}


Следующий класс добавляется динамически:

Код
.jms-wrapper {
  width: auto;
  min-width: 600px;
  height: 440px;
  background-color: #fff;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .2);
  -webkit-background-clip: padding;
  -moz-background-clip: padding;
  background-clip: padding-box;
  border: 10px solid #fff;
  border: 10px solid rgba(255, 255, 255, 0.9);
  outline: none;
  transition: background-color 1s linear;
}


Класс фонового цвета определяется в атрибуте data-color для каждого слайда. Таким образом можно устанавливать разные цвета для слайдов и изменять их при переходах. (Длительность трансформаций определяется в JavaScript.)

Код
.color-1 {
  background-color: #E3D8FF;
  background-color: rgba(227, 216, 268, 1);
}
.color-2 {
  background-color: #EBBBBC;
  background-color: rgba(235, 187, 188, 1);
}
.color-3 {
  background-color: #EED9C0;
  background-color: rgba(238, 217, 192, 1);
}
.color-4 {
  background-color: #DFEBB1;
  background-color: rgba(223, 235, 177, 1);
}
.color-5{
  background-color: #C1E6E5;
  background-color: rgba(193, 230, 229, 1);
}


Кадры имеют следующие стили:

Код
width: 900px;
  height: 420px;
  display: block;
  transition: opacity 1s;
}
.step:not(.active) {
  opacity: 0;
}


Неактивные слайды имеют непрозрачность 0. Когда слайд перемещается, непрозрачность устанавливается в 1.

Внутренняя часть слайда имеет следующие стили:

Код
.jms-content{
  margin: 0px 370px 0px 20px;
  position: relative;
  clear: both;
}
.step h3{
  color: #fff;
  font-size: 52px;
  font-weight: bold;
  text-shadow: 1px 1px 1px rgba(0,0,0,0.1);
  margin: 0;
  padding: 60px 0 10px 0;
}
.step p {
  color: #fff;
  text-shadow: 1px 1px 1px rgba(0,0,0,0.1);
  font-size: 34px;
  font-weight: normal;
  position: relative;
  margin: 0;
}


Ссылка "Читаем дальше” будет использовать небольшую трансформацию: как только слайд становится активным, кнопка всплывает и проявляется:

Код
a.jms-link{
  color: #fff;
  text-transform: uppercase;
  background: linear-gradient(top, #969696 0%,#727272 100%);
  padding: 8px 15px;
  display: inline-block;
  font-size: 16px;
  font-weight: bold;
  color: #fff;
  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.3);
  box-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);
  border: 1px solid #444;
  border-radius: 4px;
  opacity: 1;
  margin-top: 40px;
  clear: both;
  transition: all 0.4s ease-in-out 1s;
}
.step:not(.active) a.jms-link{
  opacity: 0;
  margin-top: 80px;
}


Изображение будет позиционироваться абсолютно на правой стороне слайда:

Код
.step img{
  position: absolute;
  right: 0px;
  top: 30px;
}


Индикатор навигации располагается внизу:

Код
.jms-dots{
  width: 100%;
  position: absolute;
  text-align: center;
  left: 0px;
  bottom: 20px;
  z-index: 2000;
  user-select: none;
}


Свойство "user-select: none” не дает пользователю выделить текст.

Элемент span будет темной точкой:

Код
.jms-dots span{
  display: inline-block;
  position: relative;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #777;
  margin: 3px;
  cursor: pointer;
  box-shadow:
  1px 1px 1px rgba(0,0,0,0.1) inset,
  1px 1px 1px rgba(255,255,255,0.3);
}


А псевдо-элемент будет белой точкой:

Код
.jms-dots span.jms-dots-current:after{
  content: '';
  width: 8px;
  height: 8px;
  position: absolute;
  top: 2px;
  left: 2px;
  border-radius: 50%;
  background: linear-gradient(top, #ffffff 0%,#f6f6f6 47%,#ededed 100%);
}


Стрелки навигации будут позиционироваться слева и справа от слайда. Для стрелок будут использоваться фоновые изображения:

Код
.jms-arrows{
  user-select: none;
}
.jms-arrows span{
  position: absolute;
  top: 50%;
  margin-top: -40px;
  height: 80px;
  width: 30px;
  cursor: pointer;
  z-index: 2000;
  box-shadow: 1px 1px 4px rgba(0, 0, 0, 0.1);
  border-radius: 3px;
}
.jms-arrows span.jms-arrows-prev{
  background: #fff url(../images/arrow_left.png) no-repeat 50% 50%;
  left: -10px;
}
.jms-arrows span.jms-arrows-next{
  background: #fff url(../images/arrow_right.png) no-repeat 50% 50%;
  right: -10px;
}


JavaScript
Для создания слайдшоу будем использовать плагин jmpress.js. Он обладает большими возможностями, но в нашем проекте мы будем использовать только то, что нужно.

Вызываем плагин следующим образом:

Код
$( '#jms-slider' ).jmslideshow();


Для нашего проекта используются опции плагина по умолчанию:

Код
jmpressOpts : {
  // Устанавливаем окно просмотра
  viewPort : {
  height : 400,
  width : 1300,
  maxScale: 1
  },
  fullscreen : false,
  hash : { use : false },
  mouse : { clickSelects : false },
  keyboard : { use : false },
  animation : { transitionDuration : '1s' }
},


Можно вносить изменения либо при запуске слайдшоу либо при инициализации плагина. Например:

Код
// Определяем опции для jmpress
var jmpressOpts = {
  animation : { transitionDuration : '0.8s' }
};
   
// Вызываем плагин jmslideshow
$( '#jms-slideshow' ).jmslideshow( $.extend( true, { jmpressOpts : jmpressOpts }, {
  autoplay : true,
  bgColorSpeed: '0.8s',
  arrows : false
}));


Для плагина доступны следующие опции:

Код
$.JMSlideshow.defaults = {
  // Опции для плагина jmpress.
  jmpressOpts : {
  // Устанавливаем окно просмотра
  viewPort : {
  height : 400,
  width : 1300,
  maxScale: 1
  },
  fullscreen : false,
  hash : { use : false },
  mouse : { clickSelects : false },
  keyboard : { use : false },
  animation : { transitionDuration : '1s' }
  },
  // Скрыть/показать стрелки навигации
  arrows : true,
  // Скрыть/показать навигационные индикаторы
  dots : true,
  // Скорость трансформации цвета фона
  bgColorSpeed: '1s',
  // Включение/выключение слайдшоу
  autoplay : false,
  // Время показа слайда
  interval : 3500
};


При вызове плагина первой выполняется функция инициализации:

Код
_init : function( options ) {
   
  this.options = $.extend( true, {}, $.JMSlideshow.defaults, options );
   
  // Слайды
  this.$slides = $('#jms-slider').children('div');
  // Общее количество слайдов
  this.slidesCount = this.$slides.length;
  // Фоновый цвет
  this.colors = $.map( this.$slides, function( el, i ) { return $( el ).data( 'color' ); } ).join( ' ' );
  // Строим необходимую структуру для запуска jmpress
  this._layout();
  // Инициализация плагина jmpress
  this._initImpress();
  // если плагин поддерживается (функция реализована в плагине jmpress)
  if( this.support ) {
   
  // загружаем события
  this._loadEvents();
  // если установлена опция автопроигрывания, запускаем слайдшоу
  if( this.options.autoplay ) {
   
  this._startSlideshow();
   
  }
   
  }
   
},


Функция _layout строит необходимую для работы плагина структуру. Также добавляем навигационные стрелки и индикаторы, если установлены данные опции.

Код
_layout : function() {
   
  // Добавляем определенные классы для каждого шага
  this.$slides.each( function( i ) {
   
  $(this).addClass( 'jmstep' + ( i + 1 ) );
   
  } );
   
  // Заворачиваем слайды. В качестве контейнера будет использоваться элемент, для которого вызван плагин
  this.$jmsWrapper = this.$slides.wrapAll( '<div class="jms-wrapper"/>' ).parent();
   
  // Скорость трансформации для фонового цвета
  this.$jmsWrapper.css( {
  '-webkit-transition-duration' : this.options.bgColorSpeed,
  '-moz-transition-duration' : this.options.bgColorSpeed,
  '-ms-transition-duration' : this.options.bgColorSpeed,
  '-o-transition-duration' : this.options.bgColorSpeed,
  'transition-duration' : this.options.bgColorSpeed
  } );
   
  // Добавляем стрелки навигации
  if( this.options.arrows ) {
   
  this.$arrows = $( '<nav class="jms-arrows"/>' );
   
  if( this.slidesCount > 1 ) {
   
  this.$arrowPrev = $( '<span class="jms-arrows-prev"/>' ).appendTo( this.$arrows );
  this.$arrowNext = $( '<span class="jms-arrows-next"/>' ).appendTo( this.$arrows );
   
  }
   
  this.$el.append( this.$arrows )
   
  }
   
  // Добавляем индикаторы навигации
  if( this.options.dots ) {
   
  this.$dots = $( '<nav class="jms-dots"/>' );
   
  for( var i = this.slidesCount + 1; --i; ) {
   
  this.$dots.append( ( i === this.slidesCount ) ? '<span class="jms-dots-current"/>' : '<span/>' );
   
  }
   
  if( this.options.jmpressOpts.start ) {
   
  this.$start = this.$jmsWrapper.find( this.options.jmpressOpts.start ), idxSelected = 0;
   
  ( this.$start.length ) ? idxSelected = this.$start.index() : this.options.jmpressOpts.start = null;
   
  this.$dots.children().removeClass( 'jms-dots-current' ).eq( idxSelected ).addClass( 'jms-dots-current' );
   
  }
   
  this.$el.append( this.$dots )
   
  }
   
},


Инициализируем плагин jmpress в функции _initImpress. Также переопределяется метод "setActive” для переключения активного индикатора навигации.

Код
_initImpress : function() {
   
  var _self = this;
   
  this.$jmsWrapper.jmpress( this.options.jmpressOpts );
  // check if supported (function from jmpress.js):
  // it adds the class not-suported to the wrapper
  this.support = !this.$jmsWrapper.hasClass( 'not-supported' );
   
  // if not supported remove unnecessary elements
  if( !this.support ) {
   
  if( this.$arrows ) {
   
  this.$arrows.remove();
   
  }
   
  if( this.$dots ) {
   
  this.$dots.remove();
   
  }
   
  return false;
   
  }
   
  // redefine the jmpress setActive method
  this.$jmsWrapper.jmpress( 'setActive', function( slide, eventData ) {
   
  // change the pagination dot active class
  if( _self.options.dots ) {
   
  // adds the current class to the current dot/page
  _self.$dots
  .children()
  .removeClass( 'jms-dots-current' )
  .eq( slide.index() )
  .addClass( 'jms-dots-current' );
   
  }
   
  // delete all current bg colors
  this.removeClass( _self.colors );
  // add bg color class
  this.addClass( slide.data( 'color' ) );
   
  } );
   
  // add step's bg color to the wrapper
  this.$jmsWrapper.addClass( this.$jmsWrapper.jmpress('active').data( 'color' ) );
   
},


Функции _startSlideshow и _stopSlideshow запускают и останавливают слайдшоу, если установлена соответствующая опция:

Код
// Запускаем слайдшоу
  _startSlideshow : function() {
   
  var _self = this;
   
  this.slideshow = setTimeout( function() {
   
  _self.$jmsWrapper.jmpress( 'next' );
   
  if( _self.options.autoplay ) {
   
  _self._startSlideshow();
   
  }
   
  }, this.options.interval );
   
  },
  // Останавливаем слайдшоу
  _stopSlideshow : function() {
   
  if( this.options.autoplay ) {
   
  clearTimeout( this.slideshow );
  this.options.autoplay = false;
   
  }
   
  },


Загружаем события для стрелок и индикаторов навигации. Событие touchend определено в плагине, но нам нужно остановить слайдшоу, если оно генерируется.

Код
_loadEvents : function() {
   
  var _self = this;
   
  // Стрелки навигации
  if( this.$arrowPrev && this.$arrowNext ) {
   
  this.$arrowPrev.on( 'click.jmslideshow', function( event ) {
   
  _self._stopSlideshow();
   
  _self.$jmsWrapper.jmpress( 'prev' );
   
  return false;
   
  } );
   
  this.$arrowNext.on( 'click.jmslideshow', function( event ) {
   
  _self._stopSlideshow();
   
  _self.$jmsWrapper.jmpress( 'next' );
   
  return false;
   
  } );
   
  }
   
  // Индикаторы навигации
  if( this.$dots ) {
   
  this.$dots.children().on( 'click.jmslideshow', function( event ) {
   
  _self._stopSlideshow();
   
  _self.$jmsWrapper.jmpress( 'goTo', '.jmstep' + ( $(this).index() + 1 ) );
   
  return false;
   
  } );
   
  }
   
  // Событие touchend определено в плагине.
  // Нужно остановить слайдшоу, если генерируется данное событие
  this.$jmsWrapper.on( 'touchend.jmslideshow', function() {
   
  _self._stopSlideshow();
   
  } );
   
}

  • FalleN

  • 8134

  • 1

  • 239
Теги: responsive, jQuery, css3, 3D

Ссылки на статью:

Похожие статьи: