2017-06-21 87 views
0

我需要一些幫助,我的腳本。我試圖讓我的canvas上的鼠標隨着「亮點」一起移動,但它看起來比移動的方式更快。哪裏有問題?帆布徑向漸變動畫

<!DOCTYPE HTML> 
<html> 
    <head> 
    <style> 
     body { 
    position:absolute; 
     margin: 0px; 
     padding: 0px; 
     } 
     canvas{ 
    position: fixed; 
    height:900px; 
    Width:900px; 
    } 

    </style> 
    </head> 
    <body> 
    <canvas id="myCanvas"></canvas> 
    <script> 
     var canvas = document.getElementById('myCanvas'); 
     var context = canvas.getContext('2d'); 
     window.onmousemove=function(){ 
     context.clearRect(0, 0, canvas.width, canvas.height); 
     context.rect(0, 0, canvas.width, canvas.height); 

     // create radial gradient 
     var grd = context.createRadialGradient(event.clientX, event.clientY, 5, event.clientX+20, event.clientY+20, 100); 
     // light blue 
     grd.addColorStop(0, '#ffffff'); 
     // dark blue 
     grd.addColorStop(0.5, '#000000'); 

     context.fillStyle = grd; 
     context.fill(); 
     }; 

    window.onclick= function(){ 
     alert("X: " + event.clientX + " " +"Y: " + event.clientY) 
    } 
    </script> 
    </body> 
</html> 
+1

所調整的CSS畫布,沒有設置自己的width和height屬性。上下文只知道這個屬性的大小,而不是顯示的(CSS)。另外請注意,在每次鼠標移動時創建漸變通常都是一個糟糕的主意。而是在離屏畫布上繪製一次漸變,然後在正確的位置繪製此屏幕外畫布。 – Kaiido

+0

好吧,現在我明白了。謝謝 – Pawel

回答

2

由於鼠標事件沒有同步到顯示器,因此保持鼠標事件和渲染分離。鼠標事件只記錄鼠標狀態(每秒最多可達100多個樣本)。動畫幀只在能夠顯示60fps的畫布內容時呈現。

只需創建一次漸變並使用2D畫布API中的轉換函數將其移動即可。

還要確保畫布分辨率(畫布上的像素數)與畫布佔用的CSS像素數相匹配。

// start the main loop when ready 
 
requestAnimationFrame(mainLoop); 
 
// get the canvas context 
 
const ctx = can.getContext("2d"); 
 
// set up mouse 
 
document.addEventListener("mousemove", mEvent); 
 
function mEvent(e) { mouse.x = e.pageX; mouse.y = e.pageY } 
 
const mouse = { x: 0, y: 0 }; 
 
// create gardient 
 
const grad = ctx.createRadialGradient(0, 0, 0, 0, 0, 100); 
 
grad.addColorStop(0, "rgb(255,255,255)"); 
 
grad.addColorStop(1, "rgb(0,0,0)"); 
 
// requestAnimationFrame callback function 
 
function mainLoop() { 
 
    // resize canvas if needed 
 
    if (can.width !== innerWidth || can.height !== innerHeight) { 
 
    can.width = innerWidth; // resize canvas if 
 
    can.height = innerHeight; // window resized 
 
    } 
 
    // set canvas origin to the mouse coords (moves the gradient) 
 
    ctx.setTransform(1, 0, 0, 1, mouse.x, mouse.y); 
 
    ctx.fillStyle = grad; 
 
    // fill canvas with a rectangle 
 
    ctx.fillRect(-mouse.x, -mouse.y, can.width, can.height); 
 
    requestAnimationFrame(mainLoop); 
 
}
canvas { 
 
    position: absolute; 
 
    top: 0px; 
 
    left: 0px; 
 
}
<canvas id="can"></canvas>