Круговой слайдер с помощью Anime.js

Вращающиеся слайдеры с эффектом параллакс – популярный способ отображения контента. Чаще всего они располагаются в так называемом разделе “INTRO”, и их задача – представлять контент в заманчивой форме и с первого взгляда привлекать внимание посетителей к продукту, который вы продаете.

То же самое относится и к нашему слайдеру в этом уроке. Имейте в виду, что моей главной целью было продемонстрировать, как вы можете простым способом создать сложный слайдер с помощью Anime.js, включив эффекты вращения и параллакса одновременно. Если вам не нравится дизайн, вы можете легко изменить и настроить его в соответствии с вашими потребностями.

В этом руководстве мы проведем вас через процесс создания вращающегося параллаксного слайдера с использованием HTML, CSS, JavaScript и библиотеки Anime.js. С помощью этого слайдера вы сможете плавно переходить между слайдами с классной анимацией каждый раз, когда нажимаете на кнопки навигации или элементы разбивки на страницы.

HTML-часть

Мы разберем и опишем HTML-структуру вращающегося параллаксного слайдера, который вы можете использовать в качестве основы для своих веб-проектов. Эта структура является основой слайдера, который является интерактивным и визуально привлекательным. Давайте углубимся в детали:

Оболочка страницы

<section class="page-wrapper" id="wannabedev">
  <!-- ... -->
</section>

<section> Элемент с классом “page-wrapper” и атрибутом “id” “wannabedev” служит внешним контейнером для вашего слайдера. Вы можете настроить класс и идентификатор по мере необходимости в соответствии со стилем и структурой вашего проекта. Этот контейнер обеспечивает структурированное и организованное пространство для размещения вашего слайдера на вашей веб-странице.

Контейнер слайдера

<div class="slider">
  <!-- ... -->
</div>

Внутри оболочки страницы у нас есть <div> элемент с классом “slider.” В этом контейнере находится весь вращающийся слайдер. Все слайды, элементы управления навигацией и анимации будут заключены в этот элемент.

Списком слайдов

<ul class="slider-list">
  <!-- Slide 1 -->
  <li class="slider-list__item slider-list__item_active">
    <!-- Elements for Slide 1 -->
  </li>
  
  <!-- Slide 2 -->
  <li class="slider-list__item">
    <!-- Elements for Slide 2 -->
  </li>
  
  <!-- Slide 3 -->
  <li class="slider-list__item">
    <!-- Elements for Slide 3 -->
  </li>
</ul>

<ul> Элемент с классом “slider-list” представляет список слайдов внутри слайдера. Каждый слайд представлен <li> элементом с классом “slider-list__item”. Добавляя класс “slider-list__item_active” к первому слайду, вы указываете, какой слайд должен изначально отображаться как активный при загрузке ползунка. Каждый слайд представляет собой контейнер для различных элементов, таких как изображения, заголовки и дополнительный контент.

Отдельные элементы слайда

<!-- Inside each slide -->
<span class="back__element">
  <img src="assets/img/back_apple_002.png" />
</span>
<span class="main__element">
  <img src="assets/img/bottle_apple_002.png" />
</span>
<span class="front__element">
  <img src="assets/img/front_apple_002.png" />
</span>
<span class="title__element">
  <span class="title">apple</span>
</span>
<span class="more__element">
  <span class="content">
    <!-- Content for Slide -->
  </span>
</span>

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

  • back__element: Задний элемент для создания фоновых изображений.
  • main__element: основной элемент для основного контента, часто изображения.
  • front__element: Передний элемент для наложения содержимого.
  • title__element: элемент заголовка для заголовка слайда.
  • more__element: Дополнительным контентом и ссылками для слайда.

Вы можете настроить содержимое и изображения внутри этих элементов в соответствии с содержимым, которое вы хотите отобразить на каждом слайде.

Панель навигации

<div class="slider__nav-bar">
  <a class="nav-control"></a>
  <a class="nav-control"></a>
  <a class="nav-control"></a>
</div>

Панель навигации, представленная <div> элементом с классом “slider__nav-bar”, обеспечивает визуальный индикатор для слайдов. В этом примере у нас есть три элемента управления навигацией, представленные <a> элементами с классом “nav-control”. Эти элементы управления позволяют пользователям легко перемещаться между слайдами.

Элементами управления (стрелки)

<div class="slider__controls">
  <a class="slider__arrow slider__arrow_prev"></a>
  <a class="slider__arrow slider__arrow_next"></a>
</div>

Раздел управления слайдером, заключенный в <div> с классом “slider__controls”, содержит навигационные стрелки для перехода к предыдущему и следующему слайдам. Классы “slider__arrow” и “slider__arrow_prev” и “slider__arrow_next” используются для оформления этих кнопок навигации и управления ими.

Мы опустим раздел CSS из статьи, чтобы сохранить его как можно более чистым и читабельным. 
Вы всегда можете найти его в исходном коде демонстрационной страницы.

Вы можете дополнительно настроить эту структуру с помощью CSS для оформления и JavaScript для интерактивности.

Часть Javascript

Anime.js это облегченная библиотека анимации JavaScript с простым, но мощным API. Она работает со свойствами CSS, SVG, атрибутами DOM и объектами JavaScript.

Настройка HTML структуры

Для начала давайте покажем упрощенную структуру HTML для нашего вращающегося параллаксного слайдера. Нам понадобится элемент контейнера для слайдера, отдельные элементы слайда, кнопки навигации (предыдущая и следующая) и элементы разбивки на страницы. Вот структура HTML:

<!-- HTML Structure -->
<div class="slider">
  <div class="slider-list__item">Slide 1</div>
  <div class="slider-list__item">Slide 2</div>
  <!-- Add more slides as needed -->
</div>
<div class="slider__nav-bar">
  <button class="slider__arrow_prev">Previous</button>
  <button class="slider__arrow_next">Next</button>
</div>
<div class="pagination">
  <span class="nav-control">1</span>
  <span class="nav-control">2</span>
  <!-- Add more pagination items as needed -->
</div>

Класс JavaScript Slider

Установив структуру HTML, давайте создадим класс JavaScript с именем Slider для обработки всех функциональных возможностей нашего вращающегося слайдера. Конструктор инициализирует различные свойства, такие как корневой элемент, слайды, настройки анимации и привязки событий. Мы будем использовать Anime.js для выполнения анимации. Вот фрагмент кода:

class Slider {
  constructor(props) {
    this.rootElement = props.element;
    this.slides = Array.from(
      this.rootElement.querySelectorAll(".slider-list__item")
    );
    this.slidesLength = this.slides.length;
    this.current = 0;
    this.isAnimating = false;
    this.direction = 1;
    this.baseAnimeSettings = {
      rotation: 45,
      duration: 750,
      easing: 'easeInOutCirc'
    };
    this.baseAnimeSettingsBack = {
      rotation: 45,
      duration: 1850,
      elasticity: (el, i, l) => 200 + i * 200
    };
    this.baseAnimeSettingsFront = {
      rotation: 45,
      duration: 2250,
      elasticity: (el, i, l) => 200 + i * 200
    };
    this.baseAnimeSettingsTitle = {
      rotation: 45,
      duration: 1750,
      elasticity: (el, i, l) => 200 + i * 200
    };
    this.navBar = this.rootElement.querySelector(".slider__nav-bar");
    this.thumbs = Array.from(this.rootElement.querySelectorAll(".nav-control"));
    this.prevButton = this.rootElement.querySelector(".slider__arrow_prev");
    this.nextButton = this.rootElement.querySelector(".slider__arrow_next");
    this.slides[this.current].classList.add("slider-list__item_active");
    this.thumbs[this.current].classList.add("nav-control_active");
    this._bindEvents();
  }
  // Other methods go here
}

Реализация навигации

Наш goTo метод отвечает за переключение между слайдами. Когда пользователь нажимает на кнопку “Следующий” или “предыдущий” или элемент разбивки на страницы, этот метод вычисляет индекс следующего слайда и анимирует поворот и перемещение элементов для создания эффекта параллакса плавного перехода. Вот соответствующий фрагмент кода:

goTo(index, dir) {
  if (this.isAnimating) return;
  let prevSlide = this.slides[this.current];
  let nextSlide = this.slides[index];

  this.isAnimating = true;
  this.current = index;
  nextSlide.classList.add("slider-list__item_active");

  anime({
    ...this.baseAnimeSettings,
    targets: nextSlide,
    rotate: [90 * dir + 'deg', 0],
    translateX: [90 * dir + '%', 0]
  });

  anime({
    ...this.baseAnimeSettingsBack,
    targets: nextSlide.querySelectorAll('.back__element'),
    rotate: [90 * dir + 'deg', 0],
    translateX: [90 * dir + '%', 0]
  });

  anime({
    ...this.baseAnimeSettingsFront,
    targets: nextSlide.querySelectorAll('.front__element'),
    rotate: [90 * dir + 'deg', 0],
    translateX: [90 * dir + '%', 0]
  });

  anime({
    ...this.baseAnimeSettingsTitle,
    targets: nextSlide.querySelectorAll('.title__element'),
    rotate: [90 * dir + 'deg', 0],
    translateX: [90 * dir + '%', 0]
  });

  anime({
    ...this.baseAnimeSettings,
    targets: prevSlide,
    rotate: [0, -90 * dir + 'deg'],
    translateX: [0, -150 * dir + '%'],
    complete: (anim) => {
      this.isAnimating = false;
      prevSlide.classList.remove("slider-list__item_active");
      this.thumbs.forEach((item, index) => {
        const action = index === this.current ? "add" : "remove";
        item.classList[action]("nav-control_active");
      });
    }
  });

  anime({
    ...this.baseAnimeSettingsBack,
    targets: prevSlide.querySelectorAll('.back__element'),
    rotate: [0, -90 * dir + 'deg'],
    translateX: [0, -150 * dir + '%']
  });

  anime({
    ...this.baseAnimeSettingsFront,
    targets: prevSlide.querySelectorAll('.front__element'),
    rotate: [0, -90 * dir + 'deg'],
    translateX: [0, -150 * dir + '%']
  });

  anime({
    ...this.baseAnimeSettingsTitle,
    targets: prevSlide.querySelectorAll('.title__element'),
    rotate: [0, -90 * dir + 'deg'],
    translateX: [0, -150 * dir + '%']
  });
}

goStep(dir) {
  let index = this.current + dir;
  let len = this.slidesLength;
  let currentIndex = (index + len) % len;
  this.goTo(currentIndex, dir);
}

goNext() {
  this.goStep(1);
}

goPrev() {
  this.goStep(-1);
}

Создание пагинации

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

// Inside goTo method
this.thumbs.forEach((item, index) => {
  var action = index === this.current ? "add" : "remove";
  item.classList[action]("nav-control_active");
});

Пользовательские сценарии

Мы привязываем прослушиватели событий к кнопкам next и previous, а также к элементам разбивки на страницы. Когда пользователи нажимают на эти элементы, запускается соответствующее действие ползунка, вызывающего goTo метод с желаемым направлением. Вот фрагмент кода:

_bindEvents()

 {
  ["goNext", "goPrev", "_navClickHandler"].forEach((method) => {
    this[method] = this[method].bind(this);
  });
  this.nextButton.addEventListener("click", this.goNext);
  this.prevButton.addEventListener("click", this.goPrev);
  this.navBar.addEventListener("click", this._navClickHandler);
}

Инициализацией слайдера

Наконец, мы инициализируем слайдер, создавая экземпляр Slider класса, передавая корневой элемент нашего контейнера slider. Вот как вы можете это сделать:

// Initialization
let slider = new Slider({
  element: document.querySelector(".slider")
});

Заключение

Мы продемонстрировали, как создать вращающийся параллакс-слайдер с помощью JavaScript и Anime.js. С помощью этого слайдера пользователи могут плавно перемещаться по слайдам, наслаждаясь динамической анимацией, которая делает слайдер визуально привлекательным. Вы можете дополнительно настроить слайдер, изменив параметры анимации, добавив дополнительные элементы к слайдам или включив другие функции в соответствии с требованиями вашего проекта. Этот вращающийся параллаксный слайдер не только функционален, но и является отличным способом демонстрации контента в привлекательной и интерактивной форме.

Используемые ресурсы

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.