<ul>
  <li>
    <button>🦊</button>
  </li>
  <li>
    <button>🐶</button>
  </li>
  <li>
    <button>🦄</button>
  </li>
</ul>
body{
  display: flex;
  height: 100vh;
  overflow: hidden;
  justify-content: center;
  align-items: center;
  background: url(https://s3-us-west-2.amazonaws.com/s.cdpn.io/127738/unsplahBg2.jpg) no-repeat center / cover;
}
ul{
  padding: 0;
}
li{
  display: inline-block;
  list-style-type: none;
  margin: 0 20px;
  &:nth-child(1) button {
    background: #F3FFBD;
  }
  &:nth-child(2) button {
    background: #247BA0;
  }
  &:nth-child(3) button {
    background: #FF1654;
  }
}
button {
  position: relative;
  background: rebeccapurple;
  width: 200px;
  height: 200px;
  border-radius: 50%;
  border:5px solid white;
  color: white;
  font-family: Verdana;
  font-weight: bold;
  font-size: 50px;
  cursor: pointer;
  padding: 0;
}
View Compiled
class HoverButton {
  constructor(el) {
    this.el = el;
    this.hover = false;
    this.calculatePosition();
    this.attachEventsListener();
  }
  
  attachEventsListener() {
    window.addEventListener('mousemove', e => this.onMouseMove(e));
    window.addEventListener('resize', e => this.calculatePosition(e));
  }
  
  calculatePosition() {
    gsap.set(this.el, {
      x: 0,
      y: 0,
      scale: 1
    });
    const box = this.el.getBoundingClientRect();
    this.x = box.left + (box.width * 0.5);
    this.y = box.top + (box.height * 0.5);
    this.width = box.width;
    this.height = box.height;
  }
  
  onMouseMove(e) {
    let hover = false;
    let hoverArea = (this.hover ? 0.7 : 0.5);
    let x = e.clientX - this.x;
    let y = e.clientY - this.y;
    let distance = Math.sqrt( x*x + y*y );
    if (distance < (this.width * hoverArea)) {
       hover = true;
        if (!this.hover) {
          this.hover = true;
        }
        this.onHover(e.clientX, e.clientY);
    }
    
    if(!hover && this.hover) {
      this.onLeave();
      this.hover = false;
    }
  }
  
  onHover(x, y) {
    gsap.to(this.el,  {
      x: (x - this.x) * 0.4,
      y: (y - this.y) * 0.4,
      scale: 1.15,
      ease: 'power2.out',
      duration: 0.4
    });
    this.el.style.zIndex = 10;
  }
  onLeave() {
    gsap.to(this.el, {
      x: 0,
      y: 0,
      scale: 1,
      ease: 'elastic.out(1.2, 0.4)',
      duration: 0.7
    });
    this.el.style.zIndex = 1;
  }
}

const btn1 = document.querySelector('li:nth-child(1) button');
new HoverButton(btn1);

const btn2 = document.querySelector('li:nth-child(2) button');
new HoverButton(btn2);

const btn3 = document.querySelector('li:nth-child(3) button');
new HoverButton(btn3);
View Compiled

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

  1. https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.1/gsap.min.js