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 =...