JavaScript Background Parallax Effect on Mouse Move | The Great Wave by Hokusai

03/01/2022

Contents

Demo

Full Screen

Video

YouTube Channel

Code

HTML

<div id="box">
  <div class="bg layer" data-speed="1"></div>
  <div class="wave-top layer" data-speed="-10"></div>
  <div class="wave-right layer" data-speed="-1"></div>
  <div class="wave-bottom layer" data-speed="4"></div>
  <div class="wave-bottom-right layer" data-speed="1"></div>
</div>

CSS

#box {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100vh;
  background-color: #f7f0e9;
}
.bg {
  position: absolute;
  top: -5%;
  left: -5%;
  width: 110%;
  height: 110%;
  background-image: url(bg.png);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}
.wave-top {
  position: absolute;
  top: -5%;
  left: -15%;
  width: 110%;
  height: 110%;
  background-image: url(wave_top.png);
  background-position: top center;
  background-repeat: no-repeat;
  background-size: cover;
}
.wave-right {
  position: absolute;
  top: 0;
  right: 0;
  width: 110%;
  height: 110%;
  background-image: url(wave_right.png);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}
.wave-bottom {
  position: absolute;
  top: -5%;
  left: -5%;
  width: 110%;
  height: 110%;
  background-image: url(wave_bottom.png);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}
.wave-bottom-right {
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  height: 100%;
  background-image: url(wave_bottom_right.png);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}
.wave-left {
  position: absolute;
  top: 0;
  left: -1%;
  width: 120%;
  height: 120%;
  background-image: url(wave_left.png);
  background-position: center;
  background-repeat: no-repeat;
  background-size: cover;
}

JavaScript

const el = document.getElementById('box');
el.addEventListener('mousemove', parallax, false);
el.addEventListener('touchstart', parallax, false);
el.addEventListener('touchmove', parallax, false);

function parallax(event) {
  const layers = document.querySelectorAll('.layer');
  layers.forEach(layer => {
    event.preventDefault();
    let point = {};

    if(event.targetTouches) {
      point.x = event.targetTouches[0].clientX;
      point.y = event.targetTouches[0].clientY;
    } else {
      point.x = event.clientX;
      point.y = event.clientY;
    }
    const speed = layer.dataset.speed;
    const x = (el.offsetWidth - point.x * speed) / 100;
    const y = (el.offsetHeight - point.y * speed) / 100;
    layer.style.transform = `translate(${x}px, ${y}px)`;
  });
}