<div class="app" id="app">
    <audio id="wouf" src="https://www.sound-fishing.net/download.php?id=1855"></audio>
    <h1 class="title">Move the mouse for dog walking</h1>
 </div>
* {
  padding: 0;
  margin: 0;
}

body {
  overflow: hidden;
  height: 100vh;
  /** https://dev.to/alvarosaburido/use-custom-emoji-as-a-cursor-using-css-3j7 */
  cursor: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='40' height='48' viewport='0 0 100 100' style='fill:black;font-size:24px;'><text y='50%'>🐕</text></svg>")
      16 0, auto;
}

.app {
  display: flex;
  align-items: center;
  flex-direction: column;
  height: 100vh;
  width: 100%;
  background-image: linear-gradient(to top, #ffde92, #ffe19b, #ffe4a4, #ffe6ac, #ffe9b5);
}

.title {
  font-family: system-ui;
  text-transform: uppercase;
  text-align: center;
  color: white;
  font-size: 50px;
  text-shadow: 0 5px 5px #00000085;
  margin-top: 50px;
  z-index: 2;
  line-height: 50px;
}

.pow {
  position: absolute;
  width: 100px;
  height: 100px;
  opacity: 0.7;
  transform-origin: 50px;
}

.pow__center {
  position: absolute;
  height: 50px;
  width: 50px;
  top: 50px;
  left: 25px;
  background-color: #4D4637;
  border-radius: 100px;
  box-shadow: inset 5px 5px 0px 0px black;
}

.pow__finger {
  position: absolute;
  height: 25px;
  width: 25px;
  background-color: #4D4637;
  border-radius: 100%;
  box-shadow: inset 5px 5px 0px 0px black;
}

.pow__finger:nth-child(2) {
  top: 43px;
  left: 2px;
}

.pow__finger:nth-child(3) {
  top: 20px;
  left: 24px;
  height: 28px;
}

.pow__finger:nth-child(4) {
  top: 20px;
  right: 24px;
  height: 28px;
}

.pow__finger:nth-child(5) {
  top: 43px;
  right: 2px;
}
/**
 * Here is a tutorial for walking your dog !
 * Made with all my love on Twitch.tv ! <3
 *
 * Follow me :p
 * https://twitch.tv/emilienjc
 * https://github.com/EmilienLeroy
 * https://codepen.io/emilienleroy/
 * https://twitter.com/LeroyEmilien
 */
const pows = [];
const app = document.querySelector('#app');
const wouaf = document.querySelector('#wouf');
let left = false;

document.addEventListener('click', () => {
  wouaf.volume = 0.2;
  wouaf.play();
});

document.addEventListener('mousemove', (e) => {
  const previousPow = pows[pows.length - 1];

  if (pows.length === 0) {
    const pow = createPow(e.clientX, e.clientY);

    pows.push(pow);
    app.append(pow);

    return;
  }

  if (previousPow) {
    const { x, y } = previousPow.getBoundingClientRect();
    const distance = getDistance({ x: e.clientX, y: e.clientY }, { x, y });

    if (distance > 150) {
      const angle = getAngle({ x: e.clientX, y: e.clientY }, { x, y }) - 90;
      const pow = createPow(e.clientX, e.clientY, left, angle);

      left = !left;
      pows.push(pow);
      app.append(pow);

      if (pows.length > 10) {
        pows.shift().removePow();
      }
    }
  } 
});


function createPow(x, y, left = false, angle = 0) {
  const pow = document.createElement('div');
  const animation = left ?
    `rotate(${angle}deg) translate(-50px, -20px)` :
    `rotate(${angle}deg) translate(50px, -20px)`;

  pow.style.top = `${y}px`;
  pow.style.left = `${x}px`;
  pow.classList.add('pow');
  pow.innerHTML = `
    <div class="pow__center"></div>
    <div class="pow__finger"></div>
    <div class="pow__finger"></div>
    <div class="pow__finger"></div>
    <div class="pow__finger"></div>
  `;

  pow.animate([
    { 
      transform: `scale(0.9) ${animation}` ,
      opacity: '0'
    },
    { 
      transform: `scale(1) ${animation}`,
      opacity: '0.7'
    }
  ], {
    duration: 500,
    easing: 'ease',
    fill: 'both',
  })

  pow.removePow = () => {
    pow.animate([
      { opacity: 0.7 },
      { opacity: 0 }
    ], {
      duration: 1000,
      easing: 'ease',
    }).onfinish = () => pow.remove();
  }

  return pow;
}

/**
 * https://gist.github.com/conorbuck/2606166
 */
function getAngle(pos1, pos2) {
  return Math.atan2(pos2.y - pos1.y, pos2.x - pos1.x) * 180 / Math.PI;
}

/**
 * https://gist.github.com/timohausmann/5003280
 */
function getDistance(pos1, pos2) {
  let xs = pos2.x - pos1.x;
  let ys = pos2.y - pos1.y;

  ys *= ys;
  xs *= xs;

  return Math.sqrt(xs + ys);
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.