5 371 Codepen

Слежение за курсором

Скрипт описывающий принцип добавления эффекта слежения за курсором с анимацией и задержкой времени для добавления реалистичности.

HTML

<div id="el1" class="lerpme"></div>
<div id="el2" class="lerpme"></div>

CSS

body {
  cursor: none;
  width: 100vw;
  height: 100vh;
  background-image: radial-gradient(#b9d0be, #719998, #44656a);
}

.lerpme {
  box-sizing: border-box;
  position: absolute;
  border-radius: 50%;
  opacity: 0;
  pointer-events: none;
  -webkit-animation-name: reveal;
          animation-name: reveal;
  -webkit-animation-timing-function: ease-in-out;
          animation-timing-function: ease-in-out;
  -webkit-animation-duration: 1s;
          animation-duration: 1s;
  -webkit-animation-iteration-count: 1;
          animation-iteration-count: 1;
  -webkit-animation-fill-mode: forwards;
          animation-fill-mode: forwards;
}

@-webkit-keyframes reveal {
  100% {
    opacity: 1;
  }
}

@keyframes reveal {
  100% {
    opacity: 1;
  }
}
#el1 {
  width: 20vh;
  height: 20vh;
  border: 4vh solid #dd8088;
  box-shadow: 2px 2px 30px #44656a, inset 2px 2px 30px #44656a;
  -webkit-animation-delay: 0.5s;
          animation-delay: 0.5s;
}
@media (orientation: landscape) {
  #el1 {
    width: 20vw;
    height: 20vw;
    border: 4vw solid #dd8088;
  }
}

#el2 {
  width: 4vh;
  height: 4vh;
  background-color: #e6b7ad;
  box-shadow: 2px 2px 20px #44656a;
}
@media (orientation: landscape) {
  #el2 {
    width: 4vw;
    height: 4vw;
  }
}

#title {
  display: block;
  position: absolute;
  top: 75%;
  left: 50%;
  font-family: "Knewave", cursive;
  font-size: 24px;
  text-shadow: 1px 1px 3px #719998;
  text-align: center;
  color: #e4ddcb;
  -webkit-transform: translateX(-50%) translateY(-50%);
          transform: translateX(-50%) translateY(-50%);
  pointer-events: none;
}
#title::after {
  content: "A Pen by Chris Caldwell";
  display: block;
  font-family: "Raleway", sans-serif;
  font-size: 12px;
  margin-top: 1em;
  color: #44656a;
}

JS

// Variables
var mouseX = 0;
var mouseY = 0;
var mouseMoved = false;



// LERP || Linear Interpolation
function lerp(A, B, t) {
  // A = Starting position
  // B = Final position
  // t = time or percentage A and B i.e. 0.0 to 1.0
  return A + t * (B - A);
}



// Mouse Events
function handleMouseMove() {
  mouseMoved = true;
  mouseX = event.clientX;
  mouseY = event.clientY;
}
document.onmousemove = handleMouseMove;



// Construct Transform
function setTransform(element, dx, dy) {
  var transform = "translateX(" + (dx) + "px) translateY(" + (dy) + "px)";
  element.style.webkitTransform = transform;
  element.style.mozTransform = transform;
  element.style.msTransform = transform;
  element.style.oTransform = transform;
  element.style.transform = transform;  
}



// Tracking
function followMouse(element, t) {
  // Determine Start Position
  var startX = element.getBoundingClientRect().left;
  var startY = element.getBoundingClientRect().top;
  
  // Determine End Position
  var targetX = mouseX - element.offsetWidth / 2;
  var targetY = mouseY - element.offsetHeight / 2;
  
  // Determine LERP position
  var newX = lerp(startX, targetX, t);
  var newY = lerp(startY, targetY, t);
  
  // Set Position using Transforms
  setTransform(element, newX, newY);
}



// Set Position
function setPosition(element, target) {
  // Determine Position
  var targetX = target.offsetWidth / 2 - element.offsetWidth / 2;
  var targetY = target.offsetHeight / 2 - element.offsetHeight / 2;
  
  // Set Position using Transforms
  setTransform(element, targetX, targetY);  
}



// Animation
/* requestAnimationFram, or "RAF", ensures animations 
are NOT directly connected to frames. This means that 
animation draws happen smoothly, at the correct time,
and without dropping 'frames'. */
window.requestAnimationFrame(draw); // Initial 'draw' call  
function draw() {
  if (mouseMoved) {
    followMouse(el1, 0.1);
    followMouse(el2, 0.3);    
  }
  window.requestAnimationFrame(draw); // 'draw' calls itself so it can keep drawing without firing again.
}



// Handle Load
window.onload = function() {
  var el1 = document.getElementById("el1");
  var el2 = document.getElementById("el2");
  var viewport = document.body;

  // Set Initial Positions
  setPosition(el1, viewport);
  setPosition(el2, viewport);
};

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи