<!-- www.oakdigital.dk -->
<div class="oakslider">
<div class="oakslider__ui">
<div class="oakslider__nav">
<div class="oakslider__navpoint">01 <div class="oakslider__timer"><div class="timer__progress"></div></div> <span class="oakslider__label">Oak Lab Case Story</span></div>
<div class="oakslider__navpoint">02 <div class="oakslider__timer"><div class="timer__progress"></div></div> <span class="oakslider__label">Oak Lab Case Story</span></div>
<div class="oakslider__navpoint">03 <div class="oakslider__timer"><div class="timer__progress"></div></div> <span class="oakslider__label">Oak Lab Case Story</span></div>
</div>
<div class="oakslider__controls">
<div class="oakslider__arrow oakslider__arrow--left oakslider__prev"><</div>
<div class="oakslider__arrow oakslider__arrow--right oakslider__next">></div>
</div>
</div>
<div class="oakslider__slider">
<div class="oakslider__slide slide--active" data-slide="1">
<div class="slide__image"><img src="https://dbpadventures.kinsta.cloud/wp-content/uploads/2020/04/ngor-senegal-dronebillede.jpg" alt=""></div>
<div class="slide__container">
<div class="slide__content">
<div class="slide__title">The quick brown fox jumps <span class="text--highlight">over the lazy dog</span></div>
<div class="slide__link">Learn more about their approach</div>
</div>
</div>
</div>
<div class="oakslider__slide" data-slide="2">
<div class="slide__image"><img src="https://dbpadventures.kinsta.cloud/wp-content/uploads/2020/04/ngor-island-drone.jpg" alt=""></div>
<div class="slide__container">
<div class="slide__content">
<div class="slide__title">The quick brown fox jumps <span class="text--highlight">over the lazy dog</span></div>
<div class="slide__link">Learn more about their approach</div>
</div>
</div>
</div>
<div class="oakslider__slide" data-slide="3">
<div class="slide__image"><img src="https://dbpadventures.kinsta.cloud/wp-content/uploads/2020/04/strand-ngor-senegal.jpg" alt=""></div>
<div class="slide__container">
<div class="slide__content">
<div class="slide__title">The quick brown fox jumps <span class="text--highlight">over the lazy dog</span></div>
<div class="slide__link">Learn more about their approach</div>
</div>
</div>
</div>
</div>
</div>
/* www.oakdigital.dk */
body {
margin: 0;
padding: 0;
font-family: sans-serif;
}
.oakslider {
position: relative;
top: 0;
left: 0;
width: 100%;
min-height: 100vh;
background: #22273C;
color: #fff;
display: flex;
align-items: flex-start;
overflow: hidden;
}
.oakslider__ui {
position: relative;
z-index: 2;
max-width: 1200px;
min-width: 60%;
margin: 0 auto;
margin-top: 10%;
display: flex;
justify-content: space-between;
.oakslider__controls {
display: flex;
}
.oakslider__arrow {
width: 50px;
height: 50px;
border-radius: 100%;
border: 1px solid #fff;
opacity: 0.5;
background: #fff;
margin-left: 20px;
display: flex;
justify-content: center;
align-items: center;
color: black;
}
}
.oakslider__navpoint {
display: flex;
align-items: center;
margin-bottom: 10px;
font-weight: 900;
&:first-of-type {
.oakslider__timer {
width: 95px;
}
.oakslider__label {
opacity: 1;
}
}
.oakslider__label {
opacity: 0;
font-weight: 400;
}
.oakslider__timer {
position: relative;
width: 55px;
height: 1px;
background: rgba(#fff, 0.5);
margin: 0 5px;
overflow: hidden;
.timer__progress {
position: absolute;
top: 0;
left: 0;
background: #fff;
height: 1px;
width: 100%;
transform: translateX(-100%);
}
}
}
.oakslider__slide {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: none;
&.slide--active {
display: block;
}
}
.slide__image {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
img {
position: absolute;
object-fit: cover;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: .5;
}
}
.slide__container {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
.slide__content {
padding-top: 100px;
max-width: 1200px;
min-width: 60%;
font-family: sans-serif;
}
.slide__title {
font-size: 45px;
max-width: 650px;
line-height: 1.2;
font-weight: 600;
}
.slide__link {
margin-top: 25px;
}
View Compiled
/* www.oakdigital.dk */
var oakSlider = {
/*------------------------------------------------
# Slider Settings
------------------------------------------------*/
settings: {
currentSlide: 1,
totalSlides: 0,
animating: false,
autoPlay: true,
autoPlaySpeed: 8, // Increase to stay on slides for longer
transitionSpeed: 2.75, // Changes transition speed
autoPlayInterval: false,
ease: 'expo',
timeline: gsap.timeline({}),
imageScale: '',
controls: {
next: document.querySelector('.oakslider__next'),
prev: document.querySelector('.oakslider__prev'),
nav: document.querySelectorAll('.oakslider__navpoint'),
}
},
/*------------------------------------------------
# Initiate Slider
------------------------------------------------*/
init: function() {
this.settings.totalSlides = document.querySelectorAll('.oakslider__slide').length;
this.settings.controls.prev.addEventListener('click', () => { this.stopAutoPlay(); this.changeSlide('prev'); });
this.settings.controls.next.addEventListener('click', () => { this.stopAutoPlay(); this.changeSlide('next'); });
this.settings.controls.nav.forEach((el, key) => {
el.addEventListener('click', () => { this.stopAutoPlay(); this.jumpToSlide(key + 1); });
});
this.settings.imageScale = gsap.to('.slide--active .slide__image img', 15, {scale: 1.1, ease: "sine.inOut", yoyo:true, yoyoEase: true, repeat: -1});
if(this.settings.autoPlay) {
this.autoPlay();
}
},
/*------------------------------------------------
# Change Slide
------------------------------------------------*/
changeSlide: function( dir ) {
console.log(this.settings.animating);
if(this.settings.animating) return;
let animateFrom = this.settings.currentSlide;
if(dir === 'next') {
if(this.settings.currentSlide >= this.settings.totalSlides) {
this.settings.currentSlide = 1;
} else {
this.settings.currentSlide++;
}
} else {
if(this.settings.currentSlide <= 1) {
this.settings.currentSlide = this.settings.totalSlides;
} else {
this.settings.currentSlide--;
}
}
this.slideAnimation(animateFrom, this.settings.currentSlide, dir);
},
/*------------------------------------------------
# Slide Navigation
------------------------------------------------*/
jumpToSlide: function(slide) {
if(this.settings.animating || slide === this.settings.currentSlide) return;
let animateFrom = this.settings.currentSlide;
this.settings.currentSlide = slide;
if(slide > animateFrom) {
dir = 'next';
} else {
dir = 'prev';
}
this.slideAnimation(animateFrom, this.settings.currentSlide, dir);
},
/*------------------------------------------------
# Autoplaying
------------------------------------------------*/
autoPlay: function() {
this.settings.autoPlay = true;
let el = this.settings.controls.nav[this.settings.currentSlide - 1].children[0].children[0];
this.settings.timeline.fromTo(el, this.settings.autoPlaySpeed - this.settings.transitionSpeed, {
x: '-100%'
}, {
x: 0,
ease: 'none',
delay: 0.5,
onComplete: () => {
this.changeSlide('next');
}
});
},
stopAutoPlay: function() {
if(this.settings.autoPlay) {
this.settings.timeline.progress(100);
}
this.settings.autoPlay = false;
},
/*------------------------------------------------
# Update Nav
------------------------------------------------*/
updateNav: function(from, to) {
gsap.to(this.settings.controls.nav[from - 1].children[0], this.settings.transitionSpeed, {
width: 55,
ease: this.settings.ease + '.inOut',
});
gsap.to(this.settings.controls.nav[from - 1].children[1], this.settings.transitionSpeed, {
opacity: 0,
ease: this.settings.ease + '.inOut',
});
gsap.to(this.settings.controls.nav[to - 1].children[0], this.settings.transitionSpeed, {
width: 95,
ease: this.settings.ease + '.inOut',
});
gsap.to(this.settings.controls.nav[to - 1].children[1], this.settings.transitionSpeed, {
opacity: 1,
ease: this.settings.ease + '.inOut',
});
gsap.to(this.settings.controls.nav[from - 1].children[0].children[0], this.settings.transitionSpeed, {
x: '100%',
ease: this.settings.ease + '.inOut'
});
},
/*------------------------------------------------
# Slide Animation
------------------------------------------------*/
slideAnimation: function(from, to, dir) {
this.settings.animating = true;
console.log(this.settings.animating);
this.updateNav(from, to);
from = '.oakslider__slide[data-slide="' + from + '"]';
to = '.oakslider__slide[data-slide="' + to + '"]';
this.settings.timeline.clear();
this.settings.timeline.play(0);
this.settings.timeline.set(to, {display: 'block',})
.to(from + ' .slide__content *', (this.settings.transitionSpeed / 100) * 40, {
y: -20,
opacity: 0,
ease: this.settings.ease + '.in',
stagger: 0.1,
}, 'slideAnimation')
.fromTo(to + ' .slide__content *', (this.settings.transitionSpeed / 100) * 40, {
y: 20,
opacity: 0,
}, {
y: 0,
opacity: 1,
ease: 'Power3.out',
stagger: 0.1,
}, '>0.5')
.fromTo(from + ' .slide__image', this.settings.transitionSpeed, {
display: 'block',
x: '0%',
}, {
x: dir === 'next' ? '-100%' : '100%',
ease: this.settings.ease + '.inOut',
}, 'slideAnimation')
.fromTo(from + ' .slide__image img', this.settings.transitionSpeed, {
transformOrigin: 'center',
x: '0%',
}, {
x: dir === 'next' ? '50%' : '-50%',
ease: this.settings.ease + '.inOut',
}, 'slideAnimation')
.fromTo(to + ' .slide__image img', this.settings.transitionSpeed, {
transformOrigin: 'center',
x: dir === 'next' ? '-50%' : '50%',
}, {
x: '0%',
ease: this.settings.ease + '.inOut',
}, 'slideAnimation')
.fromTo(to + ' .slide__image', this.settings.transitionSpeed, {
display: 'block',
transformOrigin: 'right center',
x: dir === 'next' ? '100%' : '-100%',
}, {
x: '0%',
ease: this.settings.ease + '.inOut',
onComplete: () => {
this.settings.animating = false;
gsap.set(from, {display: 'none'});
this.settings.imageScale.kill();
gsap.set(from + ' .slide__image', {scale: 1});
this.settings.imageScale = gsap.to(to + ' .slide__image img', 15, {scale: 1.1, ease: "sine.inOut", yoyo:true, yoyoEase: true, repeat: -1});
}
}, 'slideAnimation');
if(this.settings.autoPlay) {
let el = this.settings.controls.nav[this.settings.currentSlide - 1].children[0].children[0];
this.settings.timeline.fromTo(el, this.settings.autoPlaySpeed - this.settings.transitionSpeed, {
x: '-100%'
}, {
x: 0,
ease: 'none',
onComplete: () => {
this.changeSlide('next');
}
}, '>');
}
},
};
oakSlider.init();
View Compiled
This Pen doesn't use any external CSS resources.