z-axis scroll

by sungsoonz

HTML

<div id="content">
  <div id="viewport">

    <div class="frame text" style="-webkit-transform: translateZ(-3000px);-moz-transform: translateZ(-3000px);">
      <h1>Third</h1>
    </div>
    <div class="frame text" style="-webkit-transform: translateZ(-2000px);-moz-transform: translateZ(-2000px);">
      <h1>Second</h1>
    </div>
    <div class='frame'><br /><br /><br /><br /><br /><br /></div>
    <div class="frame text" style="-webkit-transform: translateZ(-1000px);-moz-transform: translateZ(-1000px); display: block;">
      <h1>First</h1>
    </div>

  </div>

</div>

CSS

@import url('https://fonts.googleapis.com/css2?family=DotGothic16&family=Noto+Sans+JP:wght@400;700&family=Sunflower:wght@500&display=swap');

body {
  background: #ECECE9;
  height: 12750px;
}

#content {
  position: fixed;
  left: 50%;
  top: 50%;
  width: 800px;
  height: 450px;
  margin-left: -400px;
  margin-top: -225px;
}

h1 {
  font-family: 'Sunflower', sans-serif;
  text-align: center;
  font-size: 60px;
}

#viewport {
  -webkit-perspective: 300px;
  -moz-perspective: 300px;
  -webkit-perspective-origin: 50% 50%;
  -moz-perspective-origin: 50% 50%;
  -moz-transform-style: preserve-3d;
  position: relative;
  margin: 0 auto;
  width: 100%;
  height: 100%;
}

.frame {
  position: absolute;
  top: 50px;
  width: 100%;
  height: 100%;
  -moz-transform-style: preserve-3d;
  display: none;
}

.frame.text {
  width: 800px;
  margin-left: -400px;
  left: 50%;
  text-align: center;
  -moz-transform-style: preserve-3d;

}

JavaScript

let lastPos = document.body.scrollTop || document.documentElement.scrollTop,
  perspective = 300,
  zSpacing = -1000,
  zVals = [],
  frames = [...document.querySelectorAll('.frame')],
  numFrames = frames.length;


for (let i = 0; i < numFrames; i++) {
  zVals.push((numFrames - i) * zSpacing);
}

window.addEventListener('scroll', function() {
  let top = document.body.scrollTop || document.documentElement.scrollTop,
    delta = lastPos - top;

  lastPos = top;

  for (let i = 0; i < numFrames; i++) {
    let newZVal = (zVals[i] += (delta * -1.5)),
      frame = frames[i],
      transform = "translateZ(" + newZVal + "px)",
      opacity = newZVal < 200 ? 1 : 1 - parseInt((newZVal - 200) / (perspective - 200) * 10) / 10,
      display = newZVal > perspective ? "none" : "block";

     frame.setAttribute("style",
      "-webkit-transform:"+transform+";-moz-transform:"+transform+";display:"+display+";opacity:"+opacity);


  }

})