С появлением CSS3 появилась возможность совершать анимацию без использования JS-библиотек, таких, например, как jQuery. CSS3 свойство transition позволяет плавно изменять другие свойства элемента (width, height, margin, opacity и пр.), задав в качестве параметров время и закон трансформации. Предлагаю небольшую по размерам, но достаточно функциональную карусель на чистом Javascript. Небольшую, как муравей, что гораздо меньше чем сова. Но почти с такими же возможностями.
Ant-карусель позволяет:
Помещаем нашу карусель в файл index.html (пример файла см. ниже):
Здесь использованы элементы <ul><li>, но вместо них можно использовать <div > <div >, если вам это удобнее. Стрелки и индикаторные точки располагаются абсолютным позиционированием в соответствующих контейнерах. Для стрелок используются рисунки в виде треугольных скобок, которые, при желании, вы можете заменить своими рисунками или генерацией изображения псевдо-элементами :before и :after.
Создаём карусель с тремя видимыми элементами и шириной элемента 270 пикселей. Тогда максимальная ширина карусели 810 пикселей. Подключаем CSS-файл:
Располагаем элементы в контейнере ant-carousel-list, устанавливаем для него свойство display: flex и прижимаем все элементы к левому краю justify-content: flex-start. Свойство flex: 0 0 auto устанавливает flex-shrink в 0 (по умолчанию 1). Прокрутка элементов карусели осуществляется при помощи свойства transiton плавным изменением отступа margin-left от нуля до ширины элемента (в одну сторону) или от ширины элемента до нуля (в другую сторону). Для функции трансформации (прокрутки) используется значение ease.
Переходим к программе. В опциях программы можно настраивать:
Инициализация программы начинается с того, что определяется количество элементов карусели, присваиваются начальные значения внутренним переменным, назначаются обработчики событий на стрелки и точки (если подключены). Если опция автоматической прокрутки подключена, назначаются дополнительные обработчики, которые останавливают прокрутку при наведении мыши на элементы карусели. Прокрутка прикосновением срабатывает, если между точкой касания пальцем экрана и точкой отрыва пальца от экрана больше 20 пикселей и общее время прикосновения пальца к экрану меньше 80 мс. У автора пока нет большого опыта работы с данной каруселью, поэтому, возможно, приведённые значения требуют уточнения. Для более надёжного срабатывания обработчика прокрутки расстояние между точками, возможно, стоит уменьшить до 10 или 15 пикселей, а время прикосновения увеличить до 100 или 120 мс. Пользователь данной карусели может подкорректировать эти значения сам после приобретения некоторого опыта её использования.
Алгоритм прокрутки элементов отличается в зависимости от того, включена опция цикла или нет. Если включена, при прокрутке вправо (функция elemPrev) свойство margin-left всей линейки элементов this.crslList уменьшается от нуля до отрицательного значения, равного ширине элемента elemWidth. Одновременно последний элемент справа клонируется и вставляется перед первым элементом, после чего последний элемент удаляется. Линейке присваивается свойство ‘transition: margin '+ options.speed+'ms ease’, где options.speed – скорость анимации, ease – функция анимации. Теперь можно осуществлять прокрутку. Свойство margin-left плавно меняется от отрицательного значения до нуля, вся линейка плавно смещается вправо и элемент, который был последним, оказывается на первом месте. Спустя options.speed микросекунд линейке присваивается прежнее значение ’transition: none’.
Если нужно прокрутить n элементов одновременно, перестановка элементов осуществляется в цикле n раз, а расстояние margin-left увеличивается в n раз.
Прокрутка влево (функция elemNext) происходит в обратном порядке. Сначала линейке this.crslList присваивается свойство ‘transition: margin '+ options.speed+'ms ease’ и линейка плавно прокручивается влево (crslList.style.marginLeft = '-' + elemWidth + 'px'). Далее спустя options.speed микросекунд первый элемент клонируется и вставляется в конец линейки, после чего первый элемент удаляется. Линейке возвращается значение ‘transition: none’. Если нужно прокрутить n элементов одновременно, перестановка элементов так же, как и в предыдущем случае, осуществляется в цикле n раз и расстояние margin-left увеличивается в n раз.
Если опция цикла выключена, то в этом случае перестановок элементов нет, а вся линейка элементов смещается как единое целое влево или вправо до своих крайних точек. Линейке элементов this.crslList свойство ‘transition: margin '+ options.speed+'ms ease’ присваивается ещё при инициализации карусели и больше не удаляется.
Вызов карусели производится по имени класса ant-carousel или по идентификатору. Во втором случае можно разместить несколько каруселей на одной странице. Файл index.html с каруселью может выглядеть так:
Чтобы разместить нескольких каруселей на одной странице нужно вызывать их по идентификатору. Разные карусели могут иметь разное количество элементов.
Все изображения взяты из открытых источников
Спасибо за внимание!
Ant-карусель позволяет:
- показывать один или несколько элементов;
- элементы могут быть показаны в виде конечной или бесконечной ленты (в цикле);
- автопрокрутка элементов;
- навигация осуществляется стрелками, индикаторными точками или перелистыванием (для тактильных экранов);
- автоматически подстраивается под любую ширину экрана.
Помещаем нашу карусель в файл index.html (пример файла см. ниже):
HTML
<div class="ant-carousel"> <div class="ant-carousel-hider"> <ul class="ant-carousel-list"> <li class="ant-carousel-element"><img src="images/img1.jpg" alt="1"> <p>Описание 1</p> </li> <li class="ant-carousel-element"><img src=" images /img2.jpg" alt="2"> <p>Описание2</p> </li> … <li class="ant-carousel-element"><img src=" images /imgN.jpg" alt="N"> <p>Описание N</p> </li> </ul> </div> <div class="ant-carousel-arrow-left"></div><div class="ant-carousel-arrow-right"></div> <div class="ant-carousel-dots"></div> </div>
Здесь использованы элементы <ul><li>, но вместо них можно использовать <div > <div >, если вам это удобнее. Стрелки и индикаторные точки располагаются абсолютным позиционированием в соответствующих контейнерах. Для стрелок используются рисунки в виде треугольных скобок, которые, при желании, вы можете заменить своими рисунками или генерацией изображения псевдо-элементами :before и :after.
Создаём карусель с тремя видимыми элементами и шириной элемента 270 пикселей. Тогда максимальная ширина карусели 810 пикселей. Подключаем CSS-файл:
CSS
.ant-carousel { max-width: 810px; /* укажите здесь ваше значение */ position: relative; } .ant-carousel-hider { overflow: hidden; } .ant-carousel-list { width: auto; margin: 0; padding: 0; list-style-type: none; display: flex; justify-content: flex-start; } .ant-carousel-element { display: block; flex: 0 0 auto; width: 270px; /* укажите здесь ваше значение */ text-align: center; /* укажите здесь ваше значение */ } /* Navigation item styles */ div.ant-carousel-arrow-left, div.ant-carousel-arrow-right { width: 22px; height: 40px; position: absolute; cursor: pointer; opacity: 0.6; z-index: 2; display: block; } div.ant-carousel-arrow-left { left: -40px; top: 40%; background: url(“ant-arrow-left.png”) no-repeat; } div.ant-carousel-arrow-right { right: -40px; top: 40%; background: url(“ant-arrow-right.png”) no-repeat; } div.ant-carousel-arrow-left: hover { opacity: 1.0; } div.ant-carousel-arrow-right: hover { opacity: 1.0; } div.ant-carousel-dots { width: 100%; height: auto; position: absolute; left: 0; bottom: -30px; z-index: 2; text-align: center; } span.ant-dot { width: 10px; height: 10px; margin: 5px 7px; padding: 0; display: inline-block; background-color: #BBB; border-radius: 5px; cursor: pointer; }
Располагаем элементы в контейнере ant-carousel-list, устанавливаем для него свойство display: flex и прижимаем все элементы к левому краю justify-content: flex-start. Свойство flex: 0 0 auto устанавливает flex-shrink в 0 (по умолчанию 1). Прокрутка элементов карусели осуществляется при помощи свойства transiton плавным изменением отступа margin-left от нуля до ширины элемента (в одну сторону) или от ширины элемента до нуля (в другую сторону). Для функции трансформации (прокрутки) используется значение ease.
Переходим к программе. В опциях программы можно настраивать:
- количество видимых элементов;
- просмотр элементов в виде ленты от первого до последнего или в бесконечном цикле (лента замыкается в кольцо);
- автоматическая или ручная прокрутка элементов;
- интервал автоматической прокрутки;
- скорость анимации;
- включение/отключение элементов навигации: стрелки, индикаторные точки, перелистывание прикосновением (для тактильных экранов).
Инициализация программы начинается с того, что определяется количество элементов карусели, присваиваются начальные значения внутренним переменным, назначаются обработчики событий на стрелки и точки (если подключены). Если опция автоматической прокрутки подключена, назначаются дополнительные обработчики, которые останавливают прокрутку при наведении мыши на элементы карусели. Прокрутка прикосновением срабатывает, если между точкой касания пальцем экрана и точкой отрыва пальца от экрана больше 20 пикселей и общее время прикосновения пальца к экрану меньше 80 мс. У автора пока нет большого опыта работы с данной каруселью, поэтому, возможно, приведённые значения требуют уточнения. Для более надёжного срабатывания обработчика прокрутки расстояние между точками, возможно, стоит уменьшить до 10 или 15 пикселей, а время прикосновения увеличить до 100 или 120 мс. Пользователь данной карусели может подкорректировать эти значения сам после приобретения некоторого опыта её использования.
Алгоритм прокрутки элементов отличается в зависимости от того, включена опция цикла или нет. Если включена, при прокрутке вправо (функция elemPrev) свойство margin-left всей линейки элементов this.crslList уменьшается от нуля до отрицательного значения, равного ширине элемента elemWidth. Одновременно последний элемент справа клонируется и вставляется перед первым элементом, после чего последний элемент удаляется. Линейке присваивается свойство ‘transition: margin '+ options.speed+'ms ease’, где options.speed – скорость анимации, ease – функция анимации. Теперь можно осуществлять прокрутку. Свойство margin-left плавно меняется от отрицательного значения до нуля, вся линейка плавно смещается вправо и элемент, который был последним, оказывается на первом месте. Спустя options.speed микросекунд линейке присваивается прежнее значение ’transition: none’.
var elm, buf, this$ = this; elm = this.crslList.lastElementChild; buf = elm.cloneNode(true); this.crslList.insertBefore(buf, this.crslList.firstElementChild); this.crslList.removeChild(elm); this.crslList.style.marginLeft = '-' + this.elemWidth + 'px'; window.getComputedStyle(this.crslList). marginLeft; this.crslList.style.cssText = 'transition: margin '+this.options.speed+'ms ease;'; this.crslList.style.marginLeft = '0px'; setTimeout(function() { this$.crslList.style.cssText = 'transition: none;' }, this.options.speed);
Если нужно прокрутить n элементов одновременно, перестановка элементов осуществляется в цикле n раз, а расстояние margin-left увеличивается в n раз.
Прокрутка влево (функция elemNext) происходит в обратном порядке. Сначала линейке this.crslList присваивается свойство ‘transition: margin '+ options.speed+'ms ease’ и линейка плавно прокручивается влево (crslList.style.marginLeft = '-' + elemWidth + 'px'). Далее спустя options.speed микросекунд первый элемент клонируется и вставляется в конец линейки, после чего первый элемент удаляется. Линейке возвращается значение ‘transition: none’. Если нужно прокрутить n элементов одновременно, перестановка элементов так же, как и в предыдущем случае, осуществляется в цикле n раз и расстояние margin-left увеличивается в n раз.
var elm, buf, this$ = this; this.crslList.style.cssText = 'transition: margin '+this.options.speed+'ms ease;'; this.crslList.style.marginLeft = '-' + this.elemWidth + 'px'; setTimeout(function() { this$.crslList.style.cssText = 'transition: none;'; elm = this$.crslList.firstElementChild; buf = elm.cloneNode(true); this$.crslList.appendChild(buf); this$.crslList.removeChild(elm) this$.crslList.style.marginLeft = '0px' }, this.options.speed);
Если опция цикла выключена, то в этом случае перестановок элементов нет, а вся линейка элементов смещается как единое целое влево или вправо до своих крайних точек. Линейке элементов this.crslList свойство ‘transition: margin '+ options.speed+'ms ease’ присваивается ещё при инициализации карусели и больше не удаляется.
Вызов карусели производится по имени класса ant-carousel или по идентификатору. Во втором случае можно разместить несколько каруселей на одной странице. Файл index.html с каруселью может выглядеть так:
<!DOCTYPE html> <html lang="ru"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="viewport" content="width=device-width; initial-scale=1.0"> <title>Ant-Carousel</title> <!-- подключение стилей --> <link rel="stylesheet" type="text/css" href="ant-files/ant-carousel-styles.css"> </head> <body> … <div class="ant-carousel"> <!-- здесь ваша карусель --> … </div> … <footer> … </footer> <!-- подключение карусели --> <script src="ant-files/ant-carousel. js"></script> <!-- вызов карусели --> <script>new Ant()</script> </body> </html>
Чтобы разместить нескольких каруселей на одной странице нужно вызывать их по идентификатору. Разные карусели могут иметь разное количество элементов.
<div class="ant-carousel" id=”first”> <!-- первая карусель --> … <div class="ant-carousel" id=”second”> <!-- вторая карусель --> … <script>new Ant("first"); new Ant("second");</script>
Все изображения взяты из открытых источников
Спасибо за внимание!
