在画布上预渲染图像有什么意义吗?
一个例子,
var img; // Img object var pre = document.createElement("canvas"); pre.width = img.width; pre.height = img.height; var precon = pre.getContext("2d"); precon.drawImage(img,0); var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); for(var i =0; i < 10000; ++i) { ctx.drawImage(pre,Math.random() * canvas.width,Math.random() * canvas.height); }
我没有看到这一点,因为你仍然在调用context.drawImage而不管你做什么,除非画布api更快地从画布对象而不是图像对象中绘制图像?
解决方法
首先,我必须说你的例子不适合突出画布预渲染的需要和好处.
如果你需要多次绘制需要在画布上进行大量计算的东西,我会给你一个更好的例子.
假设你有这个绘图功能:
function complexDraw(ctx){ ctx.drawImage(img,width,height); // heavy computation goes here // some transforms maybe ctx.ctx.setTransform(-1,1,200,200); ctx.fillStyle = "rgba(100,100,255,0.5)"; ctx.fillRect(50,50,100); //maybe draw another img/video/canvas ctx.drawImage(anotherImg,height); // ... } function draw(){ complexDraw(ctx); }
现在让我们假设你想在画布上显示当前时间.这意味着我们将在draw函数的底部添加它:
function drawTime(ctx){ ctx.fillText(new Date().getTime(),10,50); }
现在我们的绘图功能看起来像这样:
function draw(){ complexDraw(ctx); drawTime(ctx); }
setInterval(draw,1000);
这实际上意味着每一秒你都在做一些繁重的计算只是为了更新一个愚蠢的小文本.
如果只有一种方法可以分割绘制函数并只计算需要计算的东西(那些改变的东西)……但是有:对画布预渲染问好!
关键的想法是在一个单独的画布上绘制不会改变(并且不需要重新计算)的部分 – 让我们称之为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,height); drawTime(); }
现在我们基本上每秒重绘整个画布,但我们不会重新计算complexDraw中所有繁重的工作.
我只想指出,大多数基于画布的游戏不能以60fps(每秒重绘60次)运行,而不会通过预渲染或其他称为画布分层的技术(这也值得研究)进行一些性能提升.