JSFiddle - React, Tailwind, and code Playground

by secretgspot

HTML

<div id="target">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sodales ullamcorper urna, vel elementum massa pulvinar id. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Fusce in metus justo. Suspendisse tincidunt libero ullamcorper eros mollis faucibus. Praesent a congue lacus. Phasellus ac eros justo. Vivamus arcu nisl, pharetra a viverra quis, mattis eu nulla. Donec ultrices fringilla urna nec venenatis. Etiam volutpat nisi non sapien tempus eu euismod sapien blandit. Sed pretium, diam ac viverra faucibus, metus dolor suscipit mauris, nec ornare mauris leo a metus. Pellentesque lectus ante, consectetur ut convallis vel, sagittis id nisl. Fusce viverra fringilla orci eu vestibulum.

Cras pulvinar quam purus. Aliquam tempus facilisis dolor eu tincidunt. Donec quis urna tellus, ut rutrum metus. Sed magna enim, condimentum sed hendrerit sagittis, pharetra et magna. Sed sed lorem eget nulla gravida dictum a sed sem. Mauris vel justo quam. Donec vehicula condimentum volutpat. Nullam eget aliquet nisl.

Aenean interdum massa eget tellus molestie sodales. Sed vitae libero ac risus rutrum posuere non condimentum metus. Morbi mollis nulla ac nulla accumsan vehicula. Aenean egestas tortor non sapien cursus et elementum orci consequat. Sed a enim sit amet magna laoreet bibendum. Morbi id lorem vitae enim facilisis pretium. Fusce eu dui nec enim dapibus convallis vel molestie justo. Phasellus ornare euismod commodo. Integer vitae lectus eros. Morbi tristique mattis est nec dictum. Integer at arcu lorem. Integer at urna libero.

Suspendisse potenti. Nunc eu felis neque, ac pellentesque velit. Nulla sed sapien sit amet nisi egestas porta in rhoncus mi. Quisque luctus tellus et erat pellentesque adipiscing. Mauris vulputate, elit at ullamcorper ultricies, lacus est eleifend nulla, sit amet bibendum libero ipsum vel elit. Pellentesque mollis mi fringilla dui rhoncus ac porttitor nulla ultricies. Donec vehicula tempor...

CSS

body {
  overflow:hidden;
  background:#eee;
}

#target {
  display:none;
}

.river {
  position:absolute;
  left:0;
  top:0;
  width:415px;
  height:465px;
  padding-left:50px;
}

.upper {
  height:10px;
  width:350px;
  overflow:hidden;
}

.upper > div {
  margin-bottom:50px;
}

.fall {
  width:365px;
  height:265px;
  overflow:auto;
}

.fall > div {
  margin:365px 0;
}

.lower {
  height:10px;
  width:350px;
  overflow:hidden;
}

.lower > div {
  margin-bottom:50px;
}

JavaScript

var target = document.getElementById('target');
var river = document.createElement('div');
var fall = river.cloneNode(false);
var slice = river.cloneNode(false);
var inner = river.cloneNode(false);
var slices = [];

river.className = 'river';
fall.className = 'fall';
inner.textContent = target.textContent;
fall.appendChild(inner.cloneNode(true));
river.appendChild(fall);

for (var t = fall, m, x0, x1, s, n, i = 1; i <= 10; ++i) {
  x0 = i * i;
  x1 = (i + 1) * (i + 1);
  m = 'matrix(1,0,-' + (x1 - x0 - 1) / 10 + ',1,0,0)';
  s = slice.cloneNode(false);
  s.className = 'upper';
  s.style.marginLeft = x0 + 'px';
  s.style.transform = m;
  s.style.MozTransform = m;
  s.style.WebkitTransform = m;
  s.style.opacity = (10 - i) / 10;
  n = inner.cloneNode(true);
  n.style.marginTop = i * 10 + 365 + 'px';
  s.appendChild(n);
  river.insertBefore(s, t);
  slices.push(s);
  t = s;

  x1 = x0;
  x0 = (i - 1) * (i - 1);
  m = 'matrix(1,0,-' + (x1 - x0 - 1) / 10 + ',1,0,0)';
  s = slice.cloneNode(false);
  s.className = 'lower';
  s.style.marginLeft = -x0 + 'px';
  s.style.transform = m;
  s.style.MozTransform = m;
  s.style.WebkitTransform = m;
  s.style.opacity = (10 - i) / 10;
  n = inner.cloneNode(true);
  n.style.marginTop = 110 - i * 10 + 'px';
  s.appendChild(n);
  river.appendChild(s);
  slices.push(s);
}

function adjust() {
  for (var y = fall.scrollTop, l = slices.length, i = 0; i < l; ++i)
    slices[i].scrollTop = y;
}

fall.addEventListener('scroll', adjust, false);

document.body.appendChild(river);
fall.scrollTop = 365;
adjust();