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);
}
})