90 votes

Est-ce que HTML5 / Canvas prend en charge la mise en mémoire tampon double?

Ce que j'aimerais faire, c'est dessiner mes graphiques sur un tampon, puis pouvoir le copier tel quel sur le canevas afin que je puisse faire de l'animation et éviter les scintillements. Mais je n'ai pas trouvé cette option. Quelqu'un sait comment je peux m'y prendre?

83voto

Fedor van Eldijk Points 636

Une méthode très simple consiste à avoir deux éléments de canevas au même emplacement d’écran et à définir la visibilité du tampon à afficher. Dessinez sur le caché et retournez lorsque vous avez terminé.

Un code:

CSS:

 canvas { border: 2px solid #000; position:absolute; top:0;left:0; 
visibility: hidden; }
 

Retournement dans JS:

 Buffers[1-DrawingBuffer].style.visibility='hidden';
Buffers[DrawingBuffer].style.visibility='visible';

DrawingBuffer=1-DrawingBuffer;
 

Dans ce code, le tableau 'Buffers []' contient les deux objets de travail. Ainsi, lorsque vous souhaitez commencer à dessiner, vous devez toujours connaître le contexte:

 Canvas= Buffers[DrawingBuffer].getContext('2d');
 

43voto

ricksuggs Points 774

Le suivant lien utile, en plus de montrer des exemples et des avantages de l'utilisation de la double mise en tampon, montre plusieurs autres conseils de performances pour l'utilisation de l'élément html5 canvas. Il comprend des liens vers jsPerf tests, l'ensemble des résultats des tests sur tous les navigateurs dans un Browserscope base de données. Cela garantit que les conseils de performances sont vérifiées.

http://www.html5rocks.com/en/tutorials/canvas/performance/

Pour votre commodité, j'ai inclus un exemple minimal de efficace le double buffering comme décrit dans l'article.

// canvas element in DOM
var canvas1 = document.getElementById('canvas1');
var context1 = canvas1.getContext('2d');

// buffer canvas
var canvas2 = document.createElement('canvas');
canvas2.width = 150;
canvas2.height = 150;
var context2 = canvas2.getContext('2d');

// create something on the canvas
context2.beginPath();
context2.moveTo(10,10);
context2.lineTo(10,30);
context2.stroke();

//render the buffered canvas onto the original canvas element
context1.drawImage(canvas2, 0, 0);

20voto

Edward Coffey Points 368

Les navigateurs que j'ai testés gèrent tous cette mise en mémoire tampon pour vous en ne repeignant pas la toile tant que le code qui dessine votre cadre n'est pas terminé. Voir aussi la liste de diffusion du WHATWG: http://www.mail-archive.com/whatwg@lists.whatwg.org/msg19969.html

9voto

John Points 39

Pour les non-croyants, voici un code scintillant. Notez que je m'efforce explicitement d'effacer le cercle précédent.

http://coderextreme.net/basketball2.html ( http://jsfiddle.net/GzSWJ/ )

 <!DOCTYPE html>
<html>
<head><title>Basketball</title></head>
<body>
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #c3c3c3;">
Your browser does not support the canvas element.
</canvas>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

function draw_ball(ball) {
    ctx.clearRect(0, 0, 400, 400);
    ctx.fillStyle = "#FF0000";
    ctx.beginPath();
    ctx.arc(ball.x, ball.y, 30, 0, Math.PI * 2, true);
    ctx.closePath();
    ctx.fill();
}

var deltat = 1;
var ball = {};
ball.y = 0;
ball.x = 200;
ball.vy = 0;
ball.vx = 10;
ball.ay = 9.8;
ball.ax = 0.1;

function compute_position() {
    if (ball.y > 370 && ball.vy > 0) {
        ball.vy = -ball.vy * 84 / 86;
    }
    if (ball.x < 30) {
        ball.vx = -ball.vx;
        ball.ax = -ball.ax;
    } else if (ball.x > 370) {
        ball.vx = -ball.vx;
        ball.ax = -ball.ax;
    }
    ball.ax = ball.ax / 2;
    ball.vx = ball.vx * 185 / 186;
    ball.y = ball.y + ball.vy * deltat + ball.ay * deltat * deltat / 2
    ball.x = ball.x + ball.vx * deltat + ball.ax * deltat * deltat / 2
    ball.vy = ball.vy + ball.ay * deltat
    ball.vx = ball.vx + ball.ax * deltat
    draw_ball(ball);
}

setInterval(compute_position, 40);
</script></body></html>
 

6voto

Luka Points 79

Il n'y a pas de scintillement dans les navigateurs Web! Ils utilisent déjà dbl buffering pour leur rendu. Le moteur Js fera tout votre rendu avant de le montrer. En outre, la sauvegarde et la restauration du contexte ne concernent que les données de la matrice transformationnelle de la pile, et non le contenu de la zone de dessin elle-même. Donc, vous n’avez pas besoin ou ne voulez pas de tampons dbl!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X