SCSS
HTML
<script src="https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/gsap-latest-beta.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/locomotive-scroll@3.2.7/dist/locomotive-scroll.min.js"></script>
<div id="page-content">
<section class="section-test" data-scroll-section>
<h1>Section 01</h1>
</section>
<section class="section-test" data-scroll-section>
<h1>Section 02</h1>
</section>
<section class="section" data-scroll-section>
<div id="canvas-projects"></div>
<div class="p-slider | p-js-drag-area">
<div class="p-slider__inner | p-js-slider">
<div class="p-slide | p-js-slide">
<div class="p-slide__inner | p-js-slide__inner">
<img class="p-js-slide__img" src="https://images.unsplash.com/photo-1515898034510-821b204966e4?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=e471f614f6a3fc4636e162088988dcfe" alt=""
crossorigin="anonymous" draggable="false">
</div>
</div>
<div class="p-slide | p-js-slide" style="left: 120%;">
<div class="p-slide__inner | p-js-slide__inner">
<img class="p-js-slide__img" src="https://images.unsplash.com/photo-1515515332716-78b07ef2afc0?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=38f91da8907b841ddce070dcd3c24aa2" alt=""
crossorigin="anonymous" draggable="false">
</div>
</div>
<div class="p-slide | p-js-slide" style="left: 240%;">
<div class="p-slide__inner | p-js-slide__inner">
<img class="p-js-slide__img" src="https://images.unsplash.com/photo-1516563792456-57864571b2a1?ixlib=rb-0.3.5&q=85&fm=jpg&crop=entropy&cs=srgb&ixid=eyJhcHBfaWQiOjE0NTg5fQ&s=a1d08d5d28f1bcdfd27b5f1d1c0c1c43" alt=""
crossorigin="anonymous" draggable="false">
</div>
</div>
</div>
</div>
<div class="p-titles">
<div...
SCSS
$easeOutExpo: cubic-bezier(0.190, 1.000, 0.220, 1.000);
body{
position: relative;
background-color: #111;
font-family: sans-serif;
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
#page-content{
position: relative;
}
.section{
height: 100vh;
position: relative;
}
.section-test{
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
color: white;
text-transform: uppercase;
}
.dom-gl {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
//pointer-events: none;
z-index: 1;
}
.p-slider {
position: relative;
padding: 0 22.5vw;
display: flex;
align-items: center;
height: 100%;
user-select: none;
cursor: grab;
z-index: 2;
&__inner {
display: flex;
position: relative;
}
}
.p-slide {
overflow: hidden;
&:first-child {
position: relative;
}
&:not(:first-child) {
position: absolute;
top: 0;
height: 100%;
}
&__inner {
position: relative;
overflow: hidden;
width: 55vw;
padding-top: 56.5%;
}
img {
display: none;
/*
height: 100%;
width: 140%;
position: absolute;
top: 0;
left: -20%;
object-fit: cover;
will-change: transform;
*/
}
}
.p-titles {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
overflow: hidden;
pointer-events: auto;
z-index: 9999999999;
&__list {
position: absolute;
top: 0;
left: 0;
}
&__title {
display: flex;
align-items: center;
justify-content: center;
font-size: 6vw;
font-weight: bold;
letter-spacing: -0.1vw;
color: #fff;
&--proxy {
visibility: hidden;
}
}
}
.p-progress {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
height: 0.25rem;
...
JavaScript
/* Locomotive Scroll */
window.addEventListener('load', () => {
// handle smooth scroll and update planes positions
const smoothScroll = new LocomotiveScroll({
el: document.getElementById('page-content'),
smooth: true,
inertia: 0.7,
passive: true,
class: 'is-inview'
});
});
const store = {
ww: window.innerWidth,
wh: window.innerHeight,
isDevice:
navigator.userAgent.match(/Android/i) ||
navigator.userAgent.match(/webOS/i) ||
navigator.userAgent.match(/iPhone/i) ||
navigator.userAgent.match(/iPad/i) ||
navigator.userAgent.match(/iPod/i) ||
navigator.userAgent.match(/BlackBerry/i) ||
navigator.userAgent.match(/Windows Phone/i)
};
class Slider {
constructor(el, opts = {}) {
this.bindAll();
this.el = el;
this.opts = Object.assign(
{
speed: 2,
threshold: 50,
ease: 0.075
},
opts
);
this.ui = {
items: this.el.querySelectorAll('.p-js-slide'),
titles: document.querySelectorAll('.p-js-title'),
lines: document.querySelectorAll('.p-js-progress-line')
};
this.state = {
target: 0,
current: 0,
currentRounded: 0,
y: 0,
on: {
x: 0,
y: 0
},
off: 0,
progress: 0,
diff: 0,
max: 0,
min: 0,
snap: {
points: []
},
flags: {
dragging: false
}
};
this.items = [];
this.events = {
move: store.isDevice ? 'touchmove' : 'mousemove',
up: store.isDevice ? 'touchend' : 'mouseup',
down: store.isDevice ? 'touchstart' : 'mousedown'
};
this.init();
}
bindAll() {
['onDown', 'onMove', 'onUp'].forEach(fn => (this[fn] = this[fn].bind(this)));
}
init() {
return gsap.utils.pipe(this.setup(), this.on());
}
destroy() {
this.off();
this.state = null;
this.items = null;
this.opts = null;
this.ui = null;
}
on() {
const { move, up, down } =...