parallax scroll

by uto usui

HTML

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/latest/plugins/ScrollToPlugin.min.js"></script>
<h1 class="h1">parallax scroll <br>ー</h1>

<div class="wrap">
  <div class="inner">
    <section class="section">
        <ul class="area">
          <li class="layer" data-parallax="1.05"><span></span></li>
          <li class="layer" data-parallax="0.80"><span></span></li>
          <li class="layer" data-parallax="2.50"><span></span></li>
          <li class="layer" data-parallax="1.10"><span></span></li>
          <li class="layer" data-parallax="1.80"><span></span></li>
        </ul>
    </section>
  </div>
</div>
<link href="https://fonts.googleapis.com/css?family=Dancing+Script:400,700" rel="stylesheet">

SCSS

body {
  width: 100%;
	min-height: 100vh;
	padding: 2rem;
  background-image: linear-gradient(60deg, #F7CAC9 15%, #91A8D0 85%);
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

.h1 {
	margin-bottom: 1rem;
  font-family: 'Dancing Script', cursive;
  color: rgba(white, .85);
}

.wrap {
  display: flex;
  justify-content: center;
  align-items: center;
}

.inner {
  padding-right: 1em;
  padding-left: 1em;
	min-width: 300px;
}

.section {
  width: 320px;
  height: 1000px;
  overflow: hidden;
  border: 6px double currentcolor;
  background-color: rgba(black,.9);
}

.area {
	position: relative;
}

.layer {
	position: absolute;
  width: 50px;
  height: 50px;
  //
  @for $i from 1 through 5 {
    &:nth-child(#{$i}) {
      top: calc(1000px / 5 * (#{$i} - 1));
      left: calc(320px / 5 * (#{$i} - 1));
    }
  }
  > span {
    display: inline-block;
    width: 50%;
    height: 50%;
    border-radius: 48% / 39%;
    background-color: rgba(#eee, .45);
		animation: rotate 2s infinite linear;
  }
}

JavaScript

const scrollSlow = () => {

  let $window = $(window);
  let scrollTime = 3;
  let scrollDistance = 6;

  $window.on("mousewheel DOMMouseScroll", function(e) {

    e.preventDefault();

    let delta = e.originalEvent.wheelDelta || e.originalEvent.detail * 40 * -1;
    let scrollTop = $window.scrollTop();
    let finalScroll = scrollTop - delta * scrollDistance;

    TweenMax.to($window, scrollTime, {
      scrollTo : { y: finalScroll, autoKill:true },
      ease: Power1.easeOut,
      overwrite: 5
    });

  });

}
scrollSlow();

const scrollAnim = () => {
  
  let delta = 5;
  let speed = 1.5;

  $(window).scroll(() => {

    let elementScroll = $('[data-parallax]');
    let scroll = $(window).scrollTop();
    scrollHandler(scroll);

    function scrollHandler(scroll) {

      $(elementScroll).each(function() {

        let el = $(this);
        let ratio = el.attr('data-parallax');
        let offsetTop = el.offset().top - scroll;
        let translateY = offsetTop * ratio / delta * -1;

        TweenMax.to(el, speed, {
          y: translateY
        });

      });

    }

  });

};
scrollAnim();