最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Canvas pre rendering? - Stack Overflow

programmeradmin6浏览0评论

Is there any point in pre-rendering images on canvas?

An example,

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, 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);
}

I don't see the point as you are still calling context.drawImage no matter what you do, unless the canvas api is faster drawing an image from a canvas object rather than image object?

Is there any point in pre-rendering images on canvas?

An example,

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, 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);
}

I don't see the point as you are still calling context.drawImage no matter what you do, unless the canvas api is faster drawing an image from a canvas object rather than image object?

Share Improve this question asked Jun 21, 2013 at 12:54 user2251919user2251919 6752 gold badges11 silver badges23 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 20

Firstly, I must say that your example is not suitable to highlight the need and benefits of canvas pre-rendering.

I'll give you a better example were you need to draw multiple times something that requires heavy putation on a canvas.

Let's say you have this draw function :

function plexDraw(ctx){
    ctx.drawImage(img, width, height);
    // heavy putation 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(){
    plexDraw(ctx);
}

Now let's say you want to show the current time on the canvas too. That means that we're going to add this at the bottom of our draw function :

function drawTime(ctx){
    ctx.fillText(new Date().getTime(), 10, 50); 
}

And now our draw function looks like this :

function draw(){
    plexDraw(ctx);
    drawTime(ctx);
}

Since you want to always show the current time, you need to call the draw function every second :

setInterval(draw, 1000);

This actually means that every second you are doing some heavy putation just to update a silly little text.

If only there could be a way to split the draw function and pute only the things that need puting (the ones that change)... but there is: say hello to canvas pre-rendering!

The key idea is to draw the part that doesn't change (and doesn't need to be re-puted) on a separate canvas - let's call it cacheCanvas - and just copy it's content on our app's canvas whenever we want to redraw stuff :

// suppose we have a `clone` function
var cacheCanvas = clone(canvas),
    cacheCtx = cacheCanvas.getContext('2d');

// let's draw our plex stuff on the cacheCanvas
plexDraw(cacheCtx);

// modify our main `draw` function to copy the result of the `plexDraw`
// function, not to call it
function draw(){
    ctx.drawImage(cacheCanvas, width, height);
    drawTime();
}

And now we're basically redrawing the whole canvas each second, but we're not re-puting all the heavy work in plexDraw.

I just want to note that most of the canvas based games can't run at 60fps (redraw 60 times per second) without doing some performance boost with pre rendering or another technique called canvas layering (which is also worth looking into).

发布评论

评论列表(0)

  1. 暂无评论