Skew Scroll

by Hugo Vale Pereira

HTML

<!--
From: https://brad-carter.medium.com/how-to-add-smooth-skew-scrolling-in-react-dd0eddbc24a1
And: https://github.com/wrongakram/react-smooth-skew-scrolling/tree/master
-->

<div class="App">
  <div class="scroll">
    <div class="img-container">
      <img src="https://picsum.photos/200/300" alt="image" />
    </div>
    <h2>Skew <span class="outline">Scrolling</span></h2>
    <div class="img-container">
      <img src="https://picsum.photos/200/300" alt="image" />
    </div>
    <h2>Skew <span class="outline">Scrolling</span></h2>
    <div class="img-container">
      <img src="https://picsum.photos/200/300" alt="image" />
    </div>
    <h2>Skew <span class="outline">Scrolling</span></h2>
    <div class="img-container">
      <img src="https://picsum.photos/200/300" alt="image" />
    </div>
    <h2>Skew <span class="outline">Scrolling</span></h2>
    <div class="img-container">
      <img src="https://picsum.photos/200/300" alt="image" />
    </div>
    <h2>Skew <span class="outline">Scrolling</span></h2>
    <div class="img-container">
      <img src="https://picsum.photos/200/300" alt="image" />
    </div>
    <h2>Skew <span class="outline">Scrolling Last</span></h2>
  </div>
</div>

CSS

.App{
  position: fixed;
  top: 0;
  left: 0;
  height: 100%;
  width: 100%;
  overflow: hidden;
}

.scroll > * {
   display:grid;
   
  justify-items: center;
}

JavaScript

const app = document.querySelector(".App")
const scrollContainer = document.querySelector(".scroll")

const skewConfigs = {
  ease: .1,
  current: 0,
  previous: 0,
  rounded: 0,
}

window.onload = () => {
  let scrollHeight = `${scrollContainer.getBoundingClientRect().height}px`
  console.log(scrollHeight)
  document.body.style.height = scrollHeight
  requestAnimationFrame(() => skewScrolling())
  
}

const skewScrolling = () => {
  //Set Current to the vertical scroll amount
  skewConfigs.current = window.scrollY
  //Set Previous to the previous scroll position
  skewConfigs.previous +=
    (skewConfigs.current - skewConfigs.previous) * skewConfigs.ease
  //Set rounded to
  skewConfigs.rounded = Math.round(skewConfigs.previous * 100) / 100

  const difference = skewConfigs.current - skewConfigs.rounded
  const acceleration = difference / window.innerWidth
  const velocity =+ acceleration
  const skew = velocity * 7.5

  scrollContainer.style.transform = `translate3d(0, -${skewConfigs.rounded}px,0) skewY(${skew}deg)`
  
  //console.log(skewConfigs)
  requestAnimationFrame(() => skewScrolling())
}