135 votes

Dessiner un point sur HTML5 canvas

Tracer une ligne sur le HTML5 canvas est assez simple à l'aide de l' context.moveTo() et context.lineTo() fonctions.

Je ne suis pas tout à fait sûr si il est possible de dessiner un point, c'est à dire la couleur d'un pixel unique. LineTo fonction de l'habitude de dessiner un pixel de la ligne (évidemment).

Est-il une méthode pour faire cela?

182voto

Simon Sarris Points 33799

Pour des raisons de performances, de ne pas dessiner un cercle si vous pouvez l'éviter. Il suffit de dessiner un rectangle avec une largeur et une hauteur de:

ctx.fillRect(10,10,1,1); // fill in the pixel at (10,10)

177voto

HoLyVieR Points 5396

Si vous prévoyez d'attirer beaucoup de pixel, c'est beaucoup plus efficace d'utiliser les données de l'image de la toile pour faire du pixel dessin.

var canvas = document.getElementById("myCanvas");
var canvasWidth = canvas.width;
var canvasHeight = canvas.height;
var ctx = canvas.getContext("2d");
var canvasData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);

// That's how you define the value of a pixel //
function drawPixel (x, y, r, g, b, a) {
    var index = (x + y * canvasWidth) * 4;

    canvasData.data[index + 0] = r;
    canvasData.data[index + 1] = g;
    canvasData.data[index + 2] = b;
    canvasData.data[index + 3] = a;
}

// That's how you update the canvas, so that your //
// modification are taken in consideration //
function updateCanvas() {
    ctx.putImageData(canvasData, 0, 0);
}

Que vous pouvez l'utiliser de cette façon :

drawPixel(1, 1, 255, 0, 0, 255);
drawPixel(1, 2, 255, 0, 0, 255);
drawPixel(1, 3, 255, 0, 0, 255);
updateCanvas();

Pour plus d'informations, vous pouvez prendre un coup d'oeil à ce Mozilla post de blog : http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/

47voto

Salvador Dali Points 11667

Il semble étrange, mais néanmoins HTML5 prend en charge le dessin des lignes, des cercles, des rectangles et de nombreuses autres formes de base, il n'a rien d'adapté pour le dessin, le point de base. La seule façon de le faire est de simuler point avec ce que vous avez.

Donc, fondamentalement, il y a 3 solutions possibles:

  • dessiner point par une ligne
  • dessiner point par un polygone
  • dessiner point par un cercle

Chacun d'eux a ses inconvénients

Ligne

function point(x, y, canvas){
  canvas.beginPath();
  canvas.moveTo(x, y);
  canvas.lineTo(x+1, y+1);
  canvas.stroke();
}

Gardez à l'esprit que nous sommes en train pour le Sud-Est, et si c'est le bord, il peut être un problème. Mais vous pouvez aussi tirer dans une autre direction.

Rectanle

function point(x, y, canvas){
  canvas.strokeRect(x,y,1,1);
}

ou de manière plus rapide à l'aide de fillRect parce que le moteur de rendu remplira juste d'un pixel.

function point(x, y, canvas){
  canvas.fillRect(x,y,1,1);
}

Cercle

L'un des problèmes avec des cercles, c'est qu'il est plus difficile pour un moteur à rendre

function point(x, y, canvas){
  canvas.beginPath();
  canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
  canvas.stroke();
}

la même idée avec le rectangle que vous pouvez obtenir avec de remplissage.

function point(x, y, canvas){
  canvas.beginPath();
  canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
  canvas.fill();
}

Des problèmes avec toutes ces solutions:

  • il est difficile de garder une trace de tous les points que vous allez dessiner.
  • lorsque vous effectuez un zoom avant, il semble laid

Si vous vous demandez, quelle est la meilleure façon de tracer un point, je voudrais aller avec un rectangle plein. Vous pouvez voir mon jsperf ici avec des tests de comparaison

6voto

milet Points 21

Dans mon Firefox, cette astuce fonctionne:

function SetPixel(canvas, x, y)
{
  canvas.beginPath();
  canvas.moveTo(x, y);
  canvas.lineTo(x+0.4, y+0.4);
  canvas.stroke();
}

Petit décalage n'est pas visible sur l'écran, mais des forces moteur de rendu de réellement tracer un point.

6voto

wothke Points 23

La au-dessus de prétendre que "Si vous êtes planification pour en tirer beaucoup de pixel, c'est beaucoup plus efficace d'utiliser les données de l'image de la toile pour faire du pixel dessin" semble être tout à fait tort, au moins avec Chrome 31.0.1650.57 m ou selon votre définition de "beaucoup de pixel". J'aurais préféré commentaire directement à la poste, mais, malheureusement, je n'ai pas assez de stackoverflow points encore:

Je pense que je suis de dessin "beaucoup de pixels" et donc j'ai d'abord suivi les conseils respectifs pour faire bonne mesure, plus tard, j'ai changé ma mise en œuvre à un simple ctx.fillRect(..) pour chaque point tracé, voir http://www.wothke.ch/webgl_orbittrap/Orbittrap.htm

Fait intéressant, il s'avère que la bête ctx.fillRect() mise en œuvre dans mon exemple est en fait au moins deux fois plus rapide que les données images basée sur une double approche de mise en mémoire tampon.

Au moins pour mon scénario, il semble que le haut-ctx.getImageData/ctx.putImageData est en fait incroyablement LENT. (Il serait intéressant de savoir le pourcentage de pixels qui ont besoin d'être touché avant une approche fondée sur les données images pourrait prendre la tête..)

Conclusion: Si vous avez besoin pour optimiser les performances, vous devez le profil de VOTRE code et de la loi sur VOS résultats..

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