JSFiddle - React, Tailwind, and code Playground
by _nderscore
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/ScrollMagic/2.0.5/ScrollMagic.min.js"></script>
<div id="div1" class="slide">
This is div 1
</div>
<div id="div2" class="slide">
<canvas id="c"></canvas>
This is div 2
</div>
<div id="div3" class="slide">
This is div 3
</div>
<div id="div4" class="slide">
This is div 4
</div>
CSS
body { background: #262c43; color: #fff; }
div.slide { min-height: 400vh; }
#c {
width: 100vw;
height: 100vh;
position: fixed;
top: 0;
left: 0;
z-index: -1;
}
Babel + JSX
Array.from = (x)=>[].slice.call(x);
const getY = (id) =>
document.getElementById(id)
.getBoundingClientRect()
.top + window.scrollY;
const getHeight = (id) =>
document.getElementById(id)
.getBoundingClientRect()
.height;
const viewportHeight = document.documentElement.clientHeight;
const controller = window.controller = new ScrollMagic.Controller();
new ScrollMagic.Scene({
offset: getY('div2') - getHeight('div2') / 2,
duration: () => getHeight('div2') / 2
})
.on('start progress end', ({ type, progress, state }) => {
console.log('in', type, progress, state);
if (type === 'start') draw(0);
else if (type === 'end') draw(1);
else if (state === 'DURING') draw(progress);
})
.addTo(controller);
new ScrollMagic.Scene({
offset: getY('div2') + getHeight('div2') * (1 / 2),
duration: () => getHeight('div2') / 2
})
.on('start progress end', ({ type, progress, state }) => {
console.log('out', type, progress, state);
if (type === 'start') draw(0, true);
else if (type === 'end') draw(1, true);
else if (state === 'DURING') draw(progress, true);
})
.addTo(controller);
/*******/
const canvas = c;
const ctx = canvas.getContext('2d');
const COLOR = '#000000';
const SLICE_HEIGHT = 50;
const randoms = [...Array(100)].map(()=> 1 + Math.random() * 10);
window.draw = function draw(percentage, reverse) {
const width = canvas.width = document.documentElement.clientWidth;
const height = canvas.height = document.documentElement.clientHeight;
const numSlices = Math.ceil(height / SLICE_HEIGHT) + 1;
const sliceWidth = width * percentage;
ctx.fillStyle = COLOR;
for (let i = 0; i < numSlices; i++) {
/****/
const y = i * SLICE_HEIGHT;
//let scale = (percentage - (numSlices - (i + 1))) / numSlices;
let scale = Math.pow(percentage, 1 + (numSlices - (i + 1)) / numSlices);
scale = Math.max(0, Math.min(1, scale));
if (reverse)
scale = 1 - scale;
if (scale) {
const w =...