Home > Mobile >  cursor transition-duration creates slight lags
cursor transition-duration creates slight lags

Time:05-16

I am making a cursor which always points to an object.

My transition-duration unfortunately makes the cursor lag on faster movements. How do I solve this issue without getting rid of the transition duration as it smoothes the movement? Are there any alternatives?

ps. I am a JS (JQuery) newbie so if you have any improvements for my code, please let me know.

jQuery(function($) {
  let mousePos = {
    x: 0,
    y: 0
  }

  let lastMove = 0;

  function onm ouseMove(e) {
    mousePos.x = e.pageX;
    mousePos.y = e.pageY;
    $(".cursor").setAngle(calcAngle(getCenter($(".light")), getCenter($(".cursor"))));
    $(".cursor").setPos(e.pageX, e.pageY);
    lastMove = Date.now();
  }

  //gets the center
  function getCenter(container) {
    let containerCenter = {
      x: $(container).offset().left   $(container).width() / 2,
      y: $(container).offset().top   $(container).height() / 2
    };
    return containerCenter;
  }

  //calculates an angle between two elements (obj2 is pointing towards obj1)
  function calcAngle(obj1, obj2) {
    let angle = Math.atan2(obj1.x - obj2.x, -(obj1.y - obj2.y)) * (180 / Math.PI);
    return angle;
  }

  //sets the position
  $.fn.setPos = function(x, y) {
    this.css({
      "left": (x - this.width() / 2)   "px",
      "top": (y - this.height() / 2)   "px",
    });
  };

  //sets the rotation of an element
  $.fn.setAngle = function(angle) {
    this.css({
      "transform": "rotate("   angle   "deg)",
      "-webkit-transform": "rotate("   angle   "deg)"
    });
  };
  addEventListener("mousemove", onm ouseMove);
});
body {
  height: 100vh;
  background: grey;
  overflow: hidden;
}

.light {
  position: absolute;
  background-color: #fff;
  height: 200px;
  width: 200px;
  border-radius: 50%;
  left: 50%;
  top: 0;
  transform: translate(-50%, -50%);
}

.cursor {
  background-color: white;
  width: 20px;
  height: 20px;
  border: 1px solid white;
  border-radius: 10%;
  position: absolute;
  transition-duration: 200ms;
  pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<body>
  <div ></div>
  <div ></div>
</body>

CodePudding user response:

I recommend using a canvas in the future for this applications

For now you could use transform instead of top and left

  let mousePos = {
    x: 0,
    y: 0
  }

  let lastMove = 0;

  function onm ouseMove(e) {
    mousePos.x = e.pageX;
    mousePos.y = e.pageY;
    angle = calcAngle(getCenter($(".light")), getCenter($(".cursor")));
    $(".cursor").setTransform(e.pageX, e.pageY, angle);
    lastMove = Date.now();
  }

  //gets the center
  function getCenter(container) {
    let containerCenter = {
      x: $(container).offset().left   $(container).width() / 2,
      y: $(container).offset().top   $(container).height() / 2
    };
    return containerCenter;
  }

  //calculates an angle between two elements (obj2 is pointing towards obj1)
  function calcAngle(obj1, obj2) {
    let angle = Math.atan2(obj1.x - obj2.x, -(obj1.y - obj2.y)) * (180 / Math.PI);
    return angle;
  }

  //sets transform
  $.fn.setTransform = function(x, y, a) {
    x = x - this.width()
    y = y - this.height()
    this.css({
      "transform": "translate("   x   "px, "   y   "px) rotate("   a   "deg)",
      "-webkit-transform": "translate("   x   "px, "   y   "px) rotate("   a   "deg)",
    });
  };
  addEventListener("mousemove", onm ouseMove);
body {
  height: 100vh;
  background: grey;
  overflow: hidden;
}

.light {
  position: absolute;
  background-color: #fff;
  height: 200px;
  width: 200px;
  border-radius: 50%;
  left: 50%;
  top: 0;
  transform: translate(-50%, -50%);
}

.cursor {
  background-color: white;
  width: 20px;
  height: 20px;
  border: 1px solid white;
  border-radius: 10%;
  position: absolute;
  transition-duration: 100ms;
  transition-timing-function: ease-out;
  pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<body>
  <div ></div>
  <div ></div>
</body>

  • Related