How to use Scroll-driven animations in Slider

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 
&lt;script src="https://cdn.jsdelivr.net/npm/animejs@3.1.0/lib/anime.min.js" integrity="sha256-98Q574VkbV+PkxXCKSgL6jVq9mrVbS7uCdA+vt0sLS8=" crossorigin="anonymous">&lt;/script>

&lt;div class="slider" data-state="0">  
   
    &lt;div class="status">
      &lt;div class="point" data-current="0">&lt;/div>
      &lt;div class="stat" data-key="0">&lt;/div>
      &lt;div class="stat" data-key="1">&lt;/div>
      &lt;div class="stat" data-key="2">&lt;/div>
      &lt;div class="stat" data-key="3">&lt;/div>
      &lt;div class="stat" data-key="4">&lt;/div>
      &lt;div class="stat" data-key="5">&lt;/div>
    &lt;/div>
  
  &lt;div class="text">
    &lt;div class="current" data-key="0">Scroll&lt;/div>
    &lt;div data-key="1">or&lt;/div>
    &lt;div data-key="2">press&lt;/div>
    &lt;div data-key="3">up&lt;/div>
    &lt;div data-key="4">and&lt;/div>
    &lt;div data-key="5">down&lt;/div>
  &lt;/div>
    &lt;div class="image current" data-key="0" >

      &lt;img src="https://images.unsplash.com/photo-1557296387-5358ad7997bb?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
    &lt;/div>
    &lt;div class="image" data-key="1">
      &lt;img src="https://images.unsplash.com/photo-1509460913899-515f1df34fea?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
    &lt;/div>
    &lt;div class="image" data-key="2">
      &lt;img src="https://images.unsplash.com/photo-1495566273813-b897730c1d3d?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
    &lt;/div>
    &lt;div class="image" data-key="3">
      &lt;img src="https://images.unsplash.com/photo-1497450526346-652d470c83a9?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
    &lt;/div>
    &lt;div class="image" data-key="4" >
      &lt;img src="https://images.unsplash.com/photo-1571489730822-0c7332fb10ab?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
    &lt;/div>
    &lt;div class="image" data-key="5">
      &lt;img src="https://images.unsplash.com/photo-1563112605-04054b77e22d?ixlib=rb-1.2.1&amp;q=85&amp;fm=jpg&amp;crop=entropy&amp;cs=srgb&amp;ixid=eyJhcHBfaWQiOjE0NTg5fQ" alt=""/>
    &lt;/div>
  &lt;/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
  });

Leave a comment

Your email address will not be published. Required fields are marked *