JSFiddle - React, Tailwind, and code Playground
HTML
<script src="//unpkg.com/perspective.js/lib/perspective.js"></script>
<div class="wrap" id="wrap">
<div class="indicators">
<div class="indicator active"></div>
<div class="indicator"></div>
</div>
<div class="progress"></div>
<div class="container" id="container2" data-scroll-stage-id="color">
<div class="battery">
<div class="div1" data-scroll-item-id="battery"></div>
</div>
<p data-scroll-item-id="text">CHARGE BATTERIES</p>
</div>
<div class="container" id="container4" data-scroll-stage-id="transform">
<div class="showcase" data-scroll-item-id="showcase">
<p>ROTATE</p>
<p>TILL</p>
<p>YOU</p>
<p>SEE</p>
<p>THE</p>
<p>END</p>
<p>OF</p>
<p>THIS</p>
<p>SENTENCE</p>
</div>
</div>
</div>
CSS
* {
margin: 0;
padding: 0;
}
html, body {
height: 100%;
font-family: monospace,sans-serif;
}
.wrap {
height: 100%;
width: 100%;
position: relative;
}
.indicators {
position: absolute;
right: 20px;
top: 50%;
transform: translateY(-50%);
z-index: 1;
}
.indicator {
width: 12px;
height: 12px;
background-color: #bce6c1;
border-radius: 50%;
transition: .3s;
cursor: pointer;
}
.indicator:first-child {
margin-bottom: 8px;
}
.indicator:hover,
.indicator.active {
background-color: #3d8045;
}
.progress {
width: 0;
height: 5px;
position: absolute;
bottom: 0;
left: 0;
transition: .3s;
background-color: #3d8045;
z-index: 1;
}
.container {
height: 100%;
width: 100%;
position: relative;
overflow: hidden;
}
.container * {
position: absolute;
}
p {
font-size: 40px;
font-weight: bold;
color: #509b35;
cursor: default;
}
#container1 {
background-color: #fffaf1;
}
#container1 .div1 {
height: 200%;
width: 100%;
background: url('https://raw.githubusercontent.com/Leopoldthecoder/Perspective/master/docs/examples/assets/backstage.png') 0 0 repeat;
}
#container1 .div2 {
height: 200%;
width: 100%;
background: url('https://raw.githubusercontent.com/Leopoldthecoder/Perspective/master/docs/examples/assets/middlestage.png') 0 0 repeat;
z-index: 1;
}
#container1 .div3 {
height: 200%;
width: 100%;
background: url('https://raw.githubusercontent.com/Leopoldthecoder/Perspective/master/docs/examples/assets/frontstage.png') 0 0 repeat;
z-index: 1;
}
#container1 p {
top: 40%;
font-size: 40px;
width: 100%;
text-align: center;
}
#container2 {
background-color: #fffaf1;
}
#container2 .battery {
width: 300px;
height: 150px;
background-color: transparent;
border-radius: 20px;
border: solid 5px #666;
padding: 20px;
left: 50%;
top: 50%;
box-sizing: border-box;
transform: translateX(-50%) translateY(-80%);
}
#container2 .battery::after {
content: " ";
width:...
JavaScript
const wrap = document.querySelector('#wrap')
const scroll = new perspective.Scroll(wrap, {
stages: [{
"id": "color",
"scrollNumber": 10,
"transition": 200,
"items": [{
"id": "battery",
"effects": [{
"property": "width",
"start": "125px",
"end": "250px"
}, {
"property": "backgroundColor",
"start": "#fd0",
"end": "#209b35"
}]
}, {
"id": "text",
"effects": [{
"property": "color",
"start": "#fd0",
"end": "#209b35"
}]
}]
}, {
"id": "transform",
"scrollNumber": 8,
"transition": 500,
"items": [{
"id": "showcase",
"effects": [{
"property": "transform",
"start": "rotateX(0deg)",
"end": "rotateX(320deg)"
}]
}]
}]
})
const indicators = document.querySelectorAll('.indicator')
const progress = document.querySelector('.progress')
wrap.addEventListener('stage-change', event => {
const current = event.detail.current
progress.style.width = 100 * scroll.getStep() / current.config.scrollNumber + '%'
if (current.id === 'transform') {
indicators[1].classList.add('active')
indicators[0].classList.remove('active')
} else {
indicators[1].classList.remove('active')
indicators[0].classList.add('active')
}
})
wrap.addEventListener('step-change', event => {
const { current, activeStage } = event.detail
progress.style.width = 100 * current / activeStage.config.scrollNumber + '%'
})
indicators[0].addEventListener('click', _ => {
scroll.setActiveStage('color')
})
indicators[1].addEventListener('click', _ => {
scroll.setActiveStage('transform')
})