ABC Slider
HTML
<div class="cont">
<div class="slider"></div>
<ul class="nav"></div>
<div data-target='right' class="side-nav side-nav--right"></div>
<div data-target='left' class="side-nav side-nav--left"></div>
</div>
SCSS
$bgClr: rgba(#0b0f27, .83);
$txtClr: #fff;
$animSpd: 750 * 1ms; // Change also in JS
$numOfSlides: 5; // Add new city in the array in JS and a new image below
$bgPics: (
url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/537051/city--1-min-min.jpg') center center no-repeat,
url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/537051/city--2-min-min.jpg') center center no-repeat, url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/537051/city--3-min-min.jpg') center center no-repeat,
url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/537051/city--4-min-min.jpg') center center no-repeat,
url('https://s3-us-west-2.amazonaws.com/s.cdpn.io/537051/city--5-min-min.jpg') center center no-repeat
);
@mixin mediaMaxW($width) {
@media screen and (max-width: $width) {
@content;
}
}
.cont {
position: relative;
height: 100vh;
overflow: hidden;
}
.slider {
position: relative;
height: 100%;
transform: translate3d(0, 0, 0);
will-change: transform;
cursor: all-scroll;
user-select: none;
&.animation {
transition: transform $animSpd ease-in-out;
.slide__darkbg {
transition: transform $animSpd ease-in-out;
}
.slide__text {
transition: transform $animSpd ease-in-out;
}
.slide__letter {
transition: transform $animSpd ease-in-out;
}
}
}
.slide {
position: absolute;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
@for $i from 1 through $numOfSlides {
&--#{$i} {
left: 100% * ($i - 1);
}
}
&__darkbg {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
transform: translate3d(0, 0, 0);
will-change: transform;
z-index: 10;
}
&__text-wrapper {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
z-index: 15;
}
&__letter {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
top: 0;
left: 0;
width: 100%;
height: 100%;
transform: translate3d(0, 0, 0);
-webkit-text-fill-color: transparent !important;
-webkit-background-clip: text !important;
font: {
size: 50vw;;
weight: 800;
}
color: #000;
z-index: 2;
will-change: transform;
user-select: none;
}
&__text {
font: {
size: 8vw;
weight: 800;
}
text-transform: uppercase;
transform: translate3d(0, 0, 0);
letter-spacing: 12px;
color: $txtClr;
will-change: transform;
user-select: none;
}
&__text:nth-child(odd) {
z-index: 2;
}
&__text:nth-child(even) {
z-index: 1;
}
@each $item in $bgPics {
$i: index($bgPics, $item);
&--#{$i} {
&__darkbg {
left: -50% * ($i - 1);
background: $item;
background-size: cover;
background-position: 0px center, 0px center;
transform: translate3d(0, 0, 0);
will-change: transform;
&:after {
content: '';
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: $bgClr;
}
}
&__letter {
background: $item;
background-position: 0px center, 0px center;
background-size: cover;
}
}
}
}
.nav {
position: absolute;
bottom: 25px;
left: 50%;
transform: translateX(-50%);
list-style-type: none;
z-index: 10;
&__slide {
position: relative;
display: inline-block;
width: 28px;
height: 28px;
border-radius: 50%;
border: 2px solid #fff;
margin-left: 10px;
cursor: pointer;
@include mediaMaxW(400px) {
width: 22px;
height: 22px;
}
&:hover:after {
transform: translate(-50%, -50%) scale(1,1);
opacity: 1;
}
&:after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) scale(0,0);
width: 75%;
height: 75%;
border-radius: 50%;
background-color: #fff;
opacity: 0;
transition: 300ms;
}
&--1 {
margin-left: 0;
}
}
}
.nav-active {
&:after {
transform: translate(-50%, -50%) scale(1,1);
opacity: 1;
}
}
.side-nav {
position: absolute;
width: 10%;
height: 100%;
top: 0;
z-index: 20;
cursor: pointer;
opacity: 0;
transition: 300ms;
&:hover {
opacity: .1;
}
&--right {
right: 0;
background-image: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgb(238, 215, 255) 100%);
}
&--left {
left: 0;
background-image: linear-gradient(to left, rgba(255, 255, 255, 0) 0%, rgb(238, 215, 255) 100%);
}
}
html {
box-sizing: border-box;
font: {
family: 'Open Sans', sans-serif;
}
}
*, *:before, *:after {
box-sizing: inherit;
margin: 0; padding: 0;
}
body {
background-color: #000;
overflow: hidden;
}
ES6
$(document).ready(function() {
const $cont = $('.cont');
const $slider = $('.slider');
const $nav = $('.nav');
const winW = $(window).width();
const animSpd = 750; // Change also in CSS
const distOfLetGo = winW * 0.2;
let curSlide = 1;
let animation = false;
let diff = 0;
// Generating slides
let arrCities = ['Amsterdam', 'Rome', 'New—York', 'Singapore', 'Prague']; // Change number of slides in CSS also
let numOfCities = arrCities.length;
let arrCitiesDivided = [];
arrCities.map((city) => {
let length = city.length;
let letters = Math.floor(length / 4);
let exp = new RegExp(".{1," + letters + "}", "g");
arrCitiesDivided.push(city.match(exp));
});
let generateSlide = function(city) {
let frag1 = $(document.createDocumentFragment());
let frag2 = $(document.createDocumentFragment());
const numSlide = arrCities.indexOf(arrCities[city]) + 1;
const firstLetter = arrCitiesDivided[city][0].charAt(0);
const $slide =
$(`<div data-target="${numSlide}" class="slide slide--${numSlide}">
<div class="slide__darkbg slide--${numSlide}__darkbg"></div>
<div class="slide__text-wrapper slide--${numSlide}__text-wrapper"></div>
</div>`);
const letter =
$(`<div class="slide__letter slide--${numSlide}__letter">
${firstLetter}
</div>`);
for (let i = 0, length = arrCitiesDivided[city].length; i < length; i++) {
const text =
$(`<div class="slide__text slide__text--${i + 1}">
${arrCitiesDivided[city][i]}
</div>`);
frag1.append(text);
}
const navSlide = $(`<li data-target="${numSlide}" class="nav__slide nav__slide--${numSlide}"></li>`);
frag2.append(navSlide);
$nav.append(frag2);
$slide.find(`.slide--${numSlide}__text-wrapper`).append(letter).append(frag1);
$slider.append($slide);
if (arrCities[city].length <= 4) {
$('.slide--'+ numSlide).find('.slide__text').css("font-size", "12vw");
}
};
for (let i = 0, length = numOfCities; i < length; i++) {
generateSlide(i);
}
$('.nav__slide--1').addClass('nav-active');
// Navigation
function bullets(dir) {
$('.nav__slide--' + curSlide).removeClass('nav-active');
$('.nav__slide--' + dir).addClass('nav-active');
}
function timeout() {
animation = false;
}
function pagination(direction) {
animation = true;
diff = 0;
$slider.addClass('animation');
$slider.css({
'transform': 'translate3d(-' + ((curSlide - direction) * 100) + '%, 0, 0)'
});
$slider.find('.slide__darkbg').css({
'transform': 'translate3d(' + ((curSlide - direction) * 50) + '%, 0, 0)'
});
$slider.find('.slide__letter').css({
'transform': 'translate3d(0, 0, 0)',
});
$slider.find('.slide__text').css({
'transform': 'translate3d(0, 0, 0)'
});
}
function navigateRight() {
if (curSlide >= numOfCities) return;
pagination(0);
setTimeout(timeout, animSpd);
bullets(curSlide + 1);
curSlide++;
}
function navigateLeft() {
if (curSlide <= 1) return;
pagination(2);
setTimeout(timeout, animSpd);
bullets(curSlide - 1);
curSlide--;
}
function toDefault() {
pagination(1);
setTimeout(timeout, animSpd);
}
// Events
$(document).on('mousedown touchstart', '.slide', function(e) {
if (animation) return;
let target = +$(this).attr('data-target');
let startX = e.pageX || e.originalEvent.touches[0].pageX;
$slider.removeClass('animation');
$(document).on('mousemove touchmove', function(e) {
let x = e.pageX || e.originalEvent.touches[0].pageX;
diff = startX - x;
if (target === 1 && diff < 0 || target === numOfCities && diff > 0) return;
$slider.css({
'transform': 'translate3d(-' + ((curSlide - 1) * 100 + (diff / 30)) + '%, 0, 0)'
});
$slider.find('.slide__darkbg').css({
'transform': 'translate3d(' + ((curSlide - 1) * 50 + (diff / 60)) + '%, 0, 0)'
});
$slider.find('.slide__letter').css({
'transform': 'translate3d(' + (diff / 60) + 'vw, 0, 0)',
});
$slider.find('.slide__text').css({
'transform': 'translate3d(' + (diff / 15) + 'px, 0, 0)'
});
})
})
$(document).on('mouseup touchend', function(e) {
$(document).off('mousemove touchmove');
if (animation) return;
if (diff >= distOfLetGo) {
navigateRight();
} else if (diff <= -distOfLetGo) {
navigateLeft();
} else {
toDefault();
}
});
$(document).on('click', '.nav__slide:not(.nav-active)', function() {
let target = +$(this).attr('data-target');
bullets(target);
curSlide = target;
pagination(1);
});
$(document).on('click', '.side-nav', function() {
let target = $(this).attr('data-target');
if (target === 'right') navigateRight();
if (target === 'left') navigateLeft();
});
$(document).on('keydown', function(e) {
if (e.which === 39) navigateRight();
if (e.which === 37) navigateLeft();
});
$(document).on('mousewheel DOMMouseScroll', function(e) {
if (animation) return;
let delta = e.originalEvent.wheelDelta;
if (delta > 0 || e.originalEvent.detail < 0) navigateLeft();
if (delta < 0 || e.originalEvent.detail > 0) navigateRight();
});
});
2 Responses