2011-11-17 17 views
7

He realizado algunas investigaciones sobre cómo funciona el lienzo. Se supone que es el "modo inmediato", significa que no recuerda cómo se ve su dibujo, solo queda el mapa de bits cada vez que algo cambia.¿Canvas se vuelve a dibujar cada vez que cambia algo?

Esto parece sugerir que el lienzo no se vuelve a dibujar en el cambio.
Sin embargo, cuando probé lienzo en iPad (básicamente sigo dibujando líneas paralelas en el lienzo), la velocidad de cuadros se degrada rápidamente cuando hay más líneas en el lienzo. Las líneas se dibujan más lentamente y de una manera más nerviosa.

¿Esto significa que el lienzo en realidad tiene que dibujar todo en el cambio? ¿O hay otra razón para este cambio en el rendimiento?

Respuesta

11

El lienzo HTML recuerda el estado final de los píxeles después de realizar cada llamada de trazo/relleno. Nunca se vuelve a dibujar. (El navegador web puede necesitar volver a ajustar partes de la imagen final a la pantalla, por ejemplo, si otro objeto HTML se mueve sobre el lienzo y luego se aleja de nuevo, pero esto no es lo mismo que volver a emitir los comandos de dibujo.

El contexto siempre recuerda su estado actual, incluida cualquier ruta que haya estado acumulando. Es probable que (accidentalmente) no borre su ruta entre 'renovaciones', y así en el primer fotograma está dibujando una línea, en el segundo marco de dos líneas, en el tercer cuadro tres líneas, y así sucesivamente. (¿Estás llamando ctx.closePath() y ctx.beginPath()? ¿está la limpieza de la tela entre los dibujos?)

Aquí es an example mostrando que el lienzo no redibuja en sí. Incluso a decenas de miles de líneas Veo la misma velocidad de fotogramas que con cientos de líneas (con un límite de 200 fps en Chrome, ~ 240 fps en Firefox 8.0, al dibujar 10 líneas por fotograma).

var lastFrame = new Date, avgFrameMS=5, lines=0; 
function drawLine(){ 
    ctx.beginPath(); 
    ctx.moveTo(Math.random()*w,Math.random()*h); 
    ctx.lineTo(Math.random()*w,Math.random()*h); 
    ctx.closePath(); 
    ctx.stroke(); 
    var now = new Date; 
    var frameTime = now - lastFrame; 
    avgFrameMS += (frameTime-avgFrameMS)/20; 
    lastFrame = now; 
    setTimeout(drawLine,1); 
    lines++; 
} 
drawLine(); 

// Show the stats infrequently 
setInterval(function(){ 
    fps.innerHTML = (1000/avgFrameMS).toFixed(1); 
    l.innerHTML = lines; 
},1000); 

visto en acción: http://phrogz.net/tmp/canvas_refresh_rate.html

Para obtener más información sobre lo que el código está haciendo realidad frente a lo que se sospecha que está haciendo, dé su caso de prueba con nosotros.

+1

Gracias por el increíble ejemplo !!!! Encontré que el problema era simplemente que no llamaba a context.closePath() !! – Codier

+0

Gran respuesta. ¡Me gustaría que obtuvieras algunos puntos de recompensa por esto! –

Cuestiones relacionadas