2014-09-24 84 views
2

我想在平滑地跟隨光標的鼠標光標周圍的畫布上繪製一個矩形。不幸的是,mousemoved事件不能夠快速啓動,並且繪圖不斷落後於它。所以我假設我需要預測鼠標的位置,並在該點繪製矩形。我試圖編寫一個簡單的庫來將它抽象出來,但它不像我想要的那樣快速移動(事實上,快速移動是緊張的)。對於慢速運動,它跟蹤得相當好,並且比使用原始鼠標座標的簡單解決方案更好。在javascript中平滑地預測鼠標光標的位置

基本思想是mousemove用鼠標的當前位置更新一些外部變量。 requestAnimationFrame循環(Watcher函數)跟蹤這些變量及其以前的值,以計算鼠標移動的速度(在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; 
}()) 

我在做什麼錯?

這裏是上面的的jsfiddle:http://jsfiddle.net/p8Lr224p/

謝謝!

回答

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 2014-09-24 23:06:59