首先,我必須說你的例子不適合強調畫布預渲染的需要和好處。
我給你一個更好的例子,你需要多次繪製需要在畫布上進行大量計算的東西。
比方說,你有這樣的draw
功能:
function complexDraw(ctx){
ctx.drawImage(img, width, height);
// heavy computation goes here
// some transforms maybe
ctx.ctx.setTransform(-1, 0, 0, 1, 200, 200);
ctx.fillStyle = "rgba(100, 100, 255, 0.5)";
ctx.fillRect(50, 50, 100, 100);
//maybe draw another img/video/canvas
ctx.drawImage(anotherImg, width, height);
// ...
}
function draw(){
complexDraw(ctx);
}
現在讓我們假設你想顯示在畫布上的當前時間太長。這意味着,我們將在我們的draw
功能的底部添加此:
function drawTime(ctx){
ctx.fillText(new Date().getTime(), 10, 50);
}
現在我們繪製函數如下:
function draw(){
complexDraw(ctx);
drawTime(ctx);
}
既然要始終顯示當前時間,你需要調用draw
功能每秒:
setInterval(draw, 1000);
這實際上意味着每一秒你正在做一些繁重的計算只是爲了更新愚蠢的小文本。
如果只有一種方法可以將draw
函數拆分並計算出只需要計算的東西(那些會發生變化的東西)......但是還有:對canvas進行預渲染的問候!
關鍵的想法是在單獨的畫布上繪製不會改變的部分 - 我們稱之爲cacheCanvas
- 只需將它的內容複製到應用程序的畫布上要重繪的東西:
// suppose we have a `clone` function
var cacheCanvas = clone(canvas),
cacheCtx = cacheCanvas.getContext('2d');
// let's draw our complex stuff on the cacheCanvas
complexDraw(cacheCtx);
// modify our main `draw` function to copy the result of the `complexDraw`
// function, not to call it
function draw(){
ctx.drawImage(cacheCanvas, width, height);
drawTime();
}
現在我們基本上重繪整個畫布每一秒,但我們不重新計算所有繁重的工作complexDraw
。
我只是想指出,大多數的基於畫布遊戲不能以60fps(重繪每秒60次)進行,而不做一些性能提升與預渲染或者叫帆布另一種技術分層(這也值得研究)。
是的,我已經實現了分層,並發現它更容易創建像視差滾動等東西,謝謝你,這是一個輝煌的見解! – user2251919
謝謝你的回答!在我製作的帆布遊戲中,我爲每個框架渲染了幾百個反光板來紋理我的風景。這對我的鑽機並沒有什麼影響,但這會幫助我在速度較慢的計算機上加快速度。 – 2015-12-23 17:20:40