2014-09-24 3 views
2

커서를 부드럽게 따라가는 마우스 커서 주위에 캔바스에 직사각형을 그려야합니다. 불행하게도, mousemoved 이벤트는 충분히 빠르게 실행되지 않으며 드로잉은 계속해서 그 뒤를 쫓습니다. 그래서 저는 마우스가 어디에 있는지 예측하고 그 지점에서 사각형을 그릴 필요가 있다고 가정합니다. 멀리 떨어져있는 것을 추상화하는 간단한 라이브러리를 작성하려고하는데, 빠른 움직임 (사실, 빠른 움직임은 지저분한)에 대해 원하는대로 추적하지 않습니다. 느린 동작의 경우 마우스 움직임을 사용하는 단순한 솔루션보다 훨씬 잘 추적됩니다.자바 스크립트에서 마우스 커서의 위치를 ​​부드럽게 예측하기

기본 아이디어는 mousemove가 두 개의 외부 변수를 마우스의 현재 위치로 업데이트한다는 것입니다. requestAnimationFrame 루프 (감시자 함수)는 시간 경과에 따라 이러한 변수와 이전 값을 추적하여 마우스가 (x 축에서) 이동하는 속도를 계산합니다. PredictX 함수가 호출되면 현재 x 위치와 x의 마지막 변화에 속도를 곱한 값을 반환합니다. 다른 reqeustAnimationFrame 루프는 예측 된 x 값을 기반으로 사각형을 이동합니다.

var MouseLerp = (function() { 
    var MOUSELERP = {}; 
    var current_x = 0; 
    var last_x = 0; 
    var dX = 0; 
    var last_time = 0; 
    var x_speed = 0; 

    var FPS = 60; 

    function Watcher(time) { 
     var dT = time - last_time 
     if (dT > (1000/FPS)) { 
      dX = last_x - current_x; 
      last_x = current_x; 
      x_speed = dX/dT 

      last_time = time; 
     } 

     requestAnimationFrame(Watcher); 
    } 

    MOUSELERP.PredictX = function() { 
     return Math.floor((dX * x_speed) + current_x); 
    } 

    MOUSELERP.Test = function() { 
     var target_element = $(".container") 
     target_element.append('<canvas width="500" height="500" id="basecanvas"></canvas>'); 
     var base_ctx = document.getElementById("basecanvas").getContext("2d"); 

     var offset = target_element.offset() 
     var offset_x = offset.left; 
     var offset_y = offset.top; 

     var WIDTH = $(window).width(); 
     var HEIGHT = $(window).height(); 

     var FPS = 60; 

     var t1 = 0; 

     function updateRect(time) { 

      var dT = time - t1 
      if (dT > (1000/FPS)) { 
       base_ctx.clearRect(0, 0, WIDTH, HEIGHT) 
       base_ctx.beginPath(); 
       base_ctx.strokeStyle = "#FF0000"; 
       base_ctx.lineWidth = 2; 

       base_ctx.rect(MOUSELERP.PredictX(), 100, 100, 100) 
       base_ctx.stroke(); 
       t1 = time; 
      } 
      requestAnimationFrame(updateRect) 
     } 
     updateRect(); 

     $(target_element).mousemove(function (event) { 
      current_x = event.pageX - offset_x; 
     }); 

     requestAnimationFrame(Watcher); 
    } 
    MOUSELERP.Test() 
    return MOUSELERP; 
}()) 

내가 뭘 잘못하고 있니? http://jsfiddle.net/p8Lr224p/

감사 :

다음은 위의 jsfiddle입니다!

답변

4

마우스 포인터가 항상 그리기보다 빠르기 때문에 가장 좋은 방법은 사용자의 눈에 대기 시간을 인식 할 수있는 이유를 제공하는 것이 아닙니다. 따라서 사용자가 그리는 동안 마우스 커서를 끄십시오. 시각적으로 마우스 커서 역할을하는 마우스 위치에 사각형을 그립니다.

var canvas=document.getElementById("canvas"); 
 
var ctx=canvas.getContext("2d"); 
 
var $canvas=$("#canvas"); 
 
var canvasOffset=$canvas.offset(); 
 
var offsetX=canvasOffset.left; 
 
var offsetY=canvasOffset.top; 
 

 
var mouseX=0; 
 
var mouseY=0; 
 

 
canvas.style.cursor="none"; 
 

 
$("#canvas").mousemove(function(e){handleMouseMove(e);}); 
 

 
function handleMouseMove(e){ 
 
    ctx.clearRect(mouseX-1,mouseY-1,9,9); 
 
    mouseX=e.clientX-offsetX; 
 
    mouseY=e.clientY-offsetY; 
 
    ctx.fillRect(mouseX,mouseY,8,8); 
 
}
body{ background-color: ivory; } 
 
#canvas{border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<h4>Less 'lagging' when mouse is invisible & canvas draws cursor.</h4> 
 
<canvas id="canvas" width=300 height=300></canvas>
,

+1

쥐, 난 정말 마우스의 위치를 ​​예측하는 영리한 방법이 있었다 기대했다. – Joel

관련 문제