Tracer une ligne sur le canevas HTML5 est assez simple avec les fonctions context.moveTo()
et context.lineTo()
.
Je ne sais pas s'il est possible de dessiner un point, c'est-à-dire de colorer un seul pixel. La fonction lineTo ne dessine pas une seule ligne de pixel (évidemment).
Y at-il une méthode pour faire cela?
Pour des raisons de performances, ne tracez pas de cercle si vous pouvez l'éviter. Il suffit de dessiner un rectangle avec une largeur et une hauteur de un:
ctx.fillRect(10,10,1,1); // fill in the pixel at (10,10)
Si vous prévoyez de dessiner beaucoup de pixels, il est beaucoup plus efficace d’utiliser les données d’image du canevas pour dessiner au pixel.
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);
}
Alors 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 consulter cet article du blog Mozilla: http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/
Cela semble étrange, mais malgré tout, HTML5 prend en charge le dessin de lignes, de cercles, de rectangles et de nombreuses autres formes de base, il n’a rien qui convienne pour dessiner le point de base. La seule façon de le faire est de simuler un point avec tout ce que vous avez.
Donc, fondamentalement, il y a 3 solutions possibles:
Chacun d'entre 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();
}
N'oubliez pas que nous nous dirigeons vers le sud-est et que, s'il s'agit du bord, il peut y avoir un problème. Mais vous pouvez aussi dessiner dans une autre direction.
Rectangle
function point(x, y, canvas){
canvas.strokeRect(x,y,1,1);
}
ou de manière plus rapide en utilisant fillRect car le moteur de rendu ne remplira qu'un pixel.
function point(x, y, canvas){
canvas.fillRect(x,y,1,1);
}
Cercle
L’un des problèmes des cercles est qu’il est plus difficile pour un moteur de les 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 que pour le rectangle que vous pouvez réaliser avec le remplissage.
function point(x, y, canvas){
canvas.beginPath();
canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
canvas.fill();
}
Problèmes avec toutes ces solutions:
Si vous vous demandez quelle est la meilleure façon de dessiner un point , je choisirais un rectangle plein. Vous pouvez voir mon jsperf ici avec des tests de comparaison
L’affirmation ci-dessus selon laquelle "si vous prévoyez de dessiner beaucoup de pixels, il est beaucoup plus efficace d’utiliser les données d’image du canevas pour dessiner au pixel" semble tout à fait fausse, du moins avec Chrome 31.0.1650.57 m ou selon votre définition de "lot de pixels". J'aurais préféré commenter directement cet article - mais malheureusement, je n'ai pas encore assez de points de dépassement de pile:
Je pense que je dessine "beaucoup de pixels" et c'est pourquoi j'ai d'abord suivi les conseils respectifs pour faire bonne mesure. Plus tard, j'ai modifié mon implémentation en un simple ctx.fillRect (..) pour chaque point dessiné, voir http: //www.wothke.ch/webgl_orbittrap/Orbittrap.htm
Fait intéressant, il s'avère que l'implémentation stupide de ctx.fillRect () dans mon exemple est au moins deux fois plus rapide que l'approche à double tampon basée sur ImageData.
Au moins pour mon scénario, il semble que les fonctions intégrées ctx.getImageData/ctx.putImageData soient incroyablement LENTES. (Il serait intéressant de connaître le pourcentage de pixels à toucher avant qu'une approche basée sur ImageData puisse prendre les devants.)
Conclusion: Si vous souhaitez optimiser les performances, vous devez profiler votre code et agir sur vos résultats.
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();
}
Un petit décalage n'est pas visible à l'écran, mais force le moteur de rendu à dessiner un point.
Cela devrait faire le travail
//get a reference to the canvas
var ctx = $('#canvas')[0].getContext("2d");
//draw a dot
ctx.beginPath();
ctx.arc(20, 20, 10, 0, Math.PI*2, true);
ctx.closePath();
ctx.fill();