Scroll-driven animations allow you to control the playback of an animation based on the scroll position of a scroll container. This means that as you scroll up or down, the animation scrubs forward or backward.
HTML
<script src="https://cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js" integrity="sha256-98Q574VkbV+PkxXCKSgL6jVq9mrVbS7uCdA+vt0sLS8=" crossorigin="anonymous"></script>
<div class="slider" data-state="0">
<div class="status">
<div class="point" data-current="0"></div>
<div class="stat" data-key="0"></div>
<div class="stat" data-key="1"></div>
<div class="stat" data-key="2"></div>
<div class="stat" data-key="3"></div>
<div class="stat" data-key="4"></div>
<div class="stat" data-key="5"></div>
</div>
<div class="text">
<div class="current" data-key="0">Scroll</div>
<div data-key="1">or</div>
<div data-key="2">press</div>
<div data-key="3">up</div>
<div data-key="4">and</div>
<div data-key="5">down</div>
</div>
<div class="image current" data-key="0" >
<img src="https://images.unsplash.com/photo-1557296387-5358ad7997bb?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="1">
<img src="https://images.unsplash.com/photo-1509460913899-515f1df34fea?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="2">
<img src="https://images.unsplash.com/photo-1495566273813-b897730c1d3d?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="3">
<img src="https://images.unsplash.com/photo-1497450526346-652d470c83a9?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="4" >
<img src="https://images.unsplash.com/photo-1571489730822-0c7332fb10ab?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="5">
<img src="https://images.unsplash.com/photo-1563112605-04054b77e22d?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
</div>
CSS
<!-- wp:code -->
<pre class="wp-block-code"><code>Scroll-driven animations allow you to control the playback of an animation based on the scroll position of a scroll container. This means that as you scroll up or down, the animation scrubs forward or backward.
HTML
<script src="https://cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js" integrity="sha256-98Q574VkbV+PkxXCKSgL6jVq9mrVbS7uCdA+vt0sLS8=" crossorigin="anonymous"></script>
<div class="slider" data-state="0">
<div class="status">
<div class="point" data-current="0"></div>
<div class="stat" data-key="0"></div>
<div class="stat" data-key="1"></div>
<div class="stat" data-key="2"></div>
<div class="stat" data-key="3"></div>
<div class="stat" data-key="4"></div>
<div class="stat" data-key="5"></div>
</div>
<div class="text">
<div class="current" data-key="0">Scroll</div>
<div data-key="1">or</div>
<div data-key="2">press</div>
<div data-key="3">up</div>
<div data-key="4">and</div>
<div data-key="5">down</div>
</div>
<div class="image current" data-key="0" >
<img src="https://images.unsplash.com/photo-1557296387-5358ad7997bb?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="1">
<img src="https://images.unsplash.com/photo-1509460913899-515f1df34fea?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="2">
<img src="https://images.unsplash.com/photo-1495566273813-b897730c1d3d?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="3">
<img src="https://images.unsplash.com/photo-1497450526346-652d470c83a9?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="4" >
<img src="https://images.unsplash.com/photo-1571489730822-0c7332fb10ab?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
<div class="image" data-key="5">
<img src="https://images.unsplash.com/photo-1563112605-04054b77e22d?ixlib=rb-1.2.1&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
</div>
</div>
</code></pre>
<!-- /wp:code -->
JAVASCRIPT
console.clear();
const slider = document.querySelector('.slider')
const allImages = Array.from(document.querySelectorAll('.slider .image'));
let state = {
photo: 0,
animationActive: false
};
const elStatus = Array.from(document.querySelectorAll('.slider .stat'));
elStatus.forEach( stat => {
stat.addEventListener('click', () => {
if ( !state.animationActive ) {
if(stat.dataset.key!=state.photo) {
state.animationActive = true
slide(stat.dataset.key,state.photo)
}
}
});
});
// handling swipe
var mc = new Hammer(slider);
mc.add( new Hammer.Pan({ direction: Hammer.DIRECTION_ALL}) )
// listen to events...
mc.on("panup pandown", function(ev) {
if ( !state.animationActive ) {
state.animationActive = true
let dir = 1
if (ev.type=='panup') {
dir = -1
}
var next = state.photo + dir
var current = state.photo
slide(next,current)
}
});
// handling mousewhell
slider.addEventListener("wheel", function(e) {
e.stopPropagation()
if ( !state.animationActive ) {
state.animationActive = true
let dir = Math.sign(e.deltaY);
var next = state.photo + dir
var current = state.photo
slide(next,current)
}
});
document.onkeydown = function(e) {
if ( !state.animationActive ) {
state.animationActive = true
switch (e.keyCode) {
case 37:
// left
var next = state.photo - 1
var current = state.photo
slide(next,current)
break;
case 38:
// up
var next = state.photo + 1
var current = state.photo
slide(next,current)
break;
case 39:
// right
var next = state.photo + 1
var current = state.photo
slide(next,current)
break;
case 40:
// down
var next = state.photo - 1
var current = state.photo
slide(next,current)
break;
}
}
};
function slide( toSlide, currentSlide ) {
//console.log('slide: to/cur '+toSlide+' / '+currentSlide )
if ( toSlide > currentSlide ) {
var direction = 'down'
}
if ( toSlide < currentSlide ) {
var direction = 'up'
}
var ele = document.querySelector('.slider .image[data-key="'+currentSlide+'"]')
if ( toSlide < 0 ) {
toSlide = allImages.length - 1
}
if ( toSlide > allImages.length-1 ) {
toSlide = 0
}
nextPhoto = toSlide
//console.log(' nextPhoto: '+nextPhoto +' l '+allImages.length)
currentTextEle = document.querySelector(' .slider .text .current ')
nextTextEle = document.querySelector(' .slider .text div[data-key="'+toSlide+'"] ')
var textOutToTop = anime({
targets: currentTextEle,
translateX: '110vh',
duration: 700,
easing: 'linear',
autoplay: false,
complete: function(anim) {
currentTextEle.classList.remove('current')
nextTextEle.classList.add('current')
}
});
var textOutToBottom = anime({
targets: currentTextEle,
translateX: '-110vh',
duration: 700,
easing: 'linear',
autoplay: false,
complete: function(anim) {
currentTextEle.classList.remove('current')
nextTextEle.classList.add('current')
}
});
var textInFromTop = anime({
targets: nextTextEle,
translateX: [
{ value: '110vh', duration: 1 },
{ value: 0, duration: 700 }
],
opacity: [
{ value: 0, duration: 1 },
{ value: .8, duration: 700 }
],
scaleX: [
{ value: 1.7, duration: 1 },
{ value: 1, duration: 200, delay:500 }
],
easing: 'easeInQuad',
autoplay: false,
});
var textInFromBottom = anime({
targets: nextTextEle,
translateX: [
{ value: '-80vh', duration: 1 },
{ value: 0, duration: 700 }
],
opacity: [
{ value: 0, duration: 1 },
{ value: .8, duration: 700 }
],
scaleX: [
{ value: 1.7, duration: 1 },
{ value: 1, duration: 400, delay:300 }
],
easing: 'easeInQuad',
autoplay: false,
});
var eleNext = document.querySelector('.slider .image[data-key="'+toSlide+'"]')
var outToBottomAni = anime({
targets: ele,
translateY: '110vh',
duration: 700,
easing: 'linear',
autoplay: false,
complete: function(anim) {
ele.classList.remove('current')
var resetAni = anime({
targets: ele,
translateY: 0,
duration: 1,
autoplay: false,
scale: 1.4,
opacity: 0,
})
resetAni.play()
}
});
var outToTopAni = anime({
targets: ele,
translateY: '-110vh',
duration: 700,
easing: 'linear',
autoplay: false,
complete: function(anim) {
ele.classList.remove('current')
var resetAni = anime({
targets: ele,
translateY: 0,
duration: 1,
autoplay: false,
scale: 1.4,
opacity: 0,
})
resetAni.play()
}
});
var inAni = anime({
targets: eleNext,
translateY: 0,
scale: 1,
opacity: 1,
duration: 1300,
easing: 'easeOutQuart',
autoplay: false,
complete: function(anim) {
eleNext.classList.add('current')
state.animationActive = false
}
});
inAni.play()
if ( direction == 'down' ) {
outToBottomAni.play()
textOutToBottom.play()
textInFromTop.play()
}
if ( direction == 'up' ) {
outToTopAni.play()
textOutToTop.play()
textInFromBottom.play()
}
state.photo = toSlide
let statusPoint = document.querySelector('.slider .point')
statusPoint.dataset.current = toSlide
}
var allImg = document.querySelectorAll('.slider .image:not(.current)')
var init = anime({
targets: allImg,
scale: 1.4
});