Back to Museum

The Runaway Button

Nothing says "great user experience" quite like a primary call-to-action button that actively flees in terror when your cursor approaches. Good luck submitting that form!

Live Preview

Please click the submit button below to finish.

Source Code

moving_button.html
<style>
  #button-container {
    position: relative;
    width: 100%;
    height: 300px;
  }
  #ah-ha {
    position: absolute;
    transition: left 0.15s ease-out, top 0.15s ease-out;
  }
</style>

<div id="button-container">
  <button id="ah-ha">Submit Form</button>
</div>

<script>
  const container = document.getElementById('button-container');
  const button = document.getElementById('ah-ha');
  const triggerDistance = 60;

  window.onload = () => {
    const cRect = container.getBoundingClientRect();
    const bRect = button.getBoundingClientRect();
    button.style.left = (cRect.width / 2 - bRect.width / 2) + 'px';
    button.style.top = (cRect.height / 2 - bRect.height / 2) + 'px';
  };

  document.addEventListener('mousemove', (event) => {
    const mouseX = event.clientX;
    const mouseY = event.clientY;

    const btnRect = button.getBoundingClientRect();
    const btnCenterX = btnRect.left + btnRect.width / 2;
    const btnCenterY = btnRect.top + btnRect.height / 2;

    const distanceX = mouseX - btnCenterX;
    const distanceY = mouseY - btnCenterY;
    const distance = Math.sqrt(distanceX * distanceX + distanceY * distanceY);

    if (distance < triggerDistance) {
      const cRect = container.getBoundingClientRect();
      
      const maxX = cRect.width - btnRect.width;
      const maxY = cRect.height - btnRect.height;

      const randomX = Math.floor(Math.random() * maxX);
      const randomY = Math.floor(Math.random() * maxY);

      button.style.left = `${randomX}px`;
      button.style.top = `${randomY}px`;
    }
  });
</script>