lookat

by miyabi_irokoto

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
<!DOCTYPE html>
<html lang="ja"></html>
<head>
  <meta charset="UTF-8"/>
  <title></title>
  <link rel="stylesheet" href="./assets/css/style.css"/>
</head>
<body>
  <div class="container">
    <div class="lookat"></div>
  </div>
</body>

SCSS

body { 
  margin: 0;
}
.container{
  width: 100vw;
  height: 100vh;
  position: relative;
  background: #f7f7f7;
}
.lookat{
  width: 50px;
  height: 50px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background: #000;
  border-radius: 50%;
  box-shadow: 0 0 5px rgba(0,0,0,.8);
}

JavaScript

class lookat {
  constructor(target){
    
    this.gbcr = target.getBoundingClientRect();
    
    this.el = {
      target: target,
      x: this.gbcr.x,
      y: this.gbcr.y,
      w: this.gbcr.width,
      h: this.gbcr.height,
    }

    this.attraction = 2;

    this.mouse = {
      x: 0,
      y: 0,
      cx: 0,
      cy: 0
    }

    window.addEventListener('mousemove', this.mouseMove.bind(this));
    this.onRequestAnimationFrame();
  }

  mouseMove(e) {
    this.mouse.x = gsap.utils.mapRange(this.el.x, this.el.x + this.el.w, -this.attraction, this.attraction, e.clientX);
    this.mouse.y = gsap.utils.mapRange(this.el.y, this.el.y + this.el.h, -this.attraction, this.attraction, e.clientY);
  }

  onRequestAnimationFrame() {
    this.mouse.cx = gsap.utils.interpolate(this.mouse.cx, this.mouse.x, 0.1);
    this.mouse.cy = gsap.utils.interpolate(this.mouse.cy, this.mouse.y, 0.1);
    gsap.set(this.el.target, {
      x: this.mouse.cx,
      y: this.mouse.cy
    });
    
    requestAnimationFrame(() => { this.onRequestAnimationFrame() });
  }
}
new lookat(document.querySelector('.lookat'));