w3schools tag for html5 canvas

tag - html5 video youtube



Dibujando un punto en el lienzo HTML5 (6)

Esta pregunta ya tiene una respuesta aquí:

Trazar una línea en el lienzo de HTML5 es bastante sencillo utilizando las funciones context.moveTo() y context.lineTo() .

No estoy seguro de si es posible dibujar un punto, es decir, colorear un solo píxel. La función lineTo no dibujará una sola línea de píxeles (obviamente).

¿Hay un método para hacer esto?


En mi Firefox este truco funciona:

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

El desplazamiento pequeño no es visible en la pantalla, pero obliga al motor de renderizado a dibujar un punto.


Esto debería hacer el trabajo

//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();


Lo anterior afirma que "si está planeando dibujar mucho píxel, es mucho más eficiente usar los datos de imagen del lienzo para hacer el dibujo de píxeles" parece ser bastante incorrecto, al menos con Chrome 31.0.1650.57 m o dependiendo en su definición de "gran cantidad de píxeles". Hubiera preferido comentar directamente en la publicación correspondiente, pero desafortunadamente aún no tengo suficientes puntos de :

Creo que estoy dibujando "una gran cantidad de píxeles" y, por lo tanto, seguí los consejos respectivos por si acaso. Más tarde cambié mi implementación a un simple ctx.fillRect (...) para cada punto dibujado, consulte http://www.wothke.ch/webgl_orbittrap/Orbittrap.htm

Curiosamente, resulta que la implementación tonta de ctx.fillRect () en mi ejemplo es en realidad al menos dos veces más rápida que el enfoque de doble buffer basado en ImageData.

Al menos para mi caso, parece que el ctx.getImageData / ctx.putImageData incorporado es, de hecho, LENTO. (Sería interesante saber el porcentaje de píxeles que deben tocarse antes de que un enfoque basado en ImageData tome la delantera ...)

Conclusión: si necesita optimizar el rendimiento, tiene que perfilar su código y actuar según sus hallazgos.


Parece extraño, pero no obstante HTML5 admite líneas de dibujo, círculos, rectángulos y muchas otras formas básicas, no tiene nada adecuado para dibujar el punto básico. La única forma de hacerlo es simular un punto con lo que sea que tengas.

Entonces, básicamente, hay 3 soluciones posibles:

  • dibujar punto como una línea
  • dibujar punto como un polígono
  • dibujar punto como un círculo

Cada uno de ellos tiene sus inconvenientes.

Línea

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

Tenga en cuenta que estamos dibujando en dirección Sudeste, y si este es el límite, puede haber un problema. Pero también puedes dibujar en cualquier otra dirección.

Rectángulo

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

o de una manera más rápida usando fillRect porque el motor de renderizado solo llenará un píxel.

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

Circulo

Uno de los problemas con los círculos es que es más difícil para un motor representarlos

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

la misma idea que con el rectángulo que puedes lograr con el relleno.

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

Problemas con todas estas soluciones:

  • es difícil hacer un seguimiento de todos los puntos que vas a dibujar.
  • cuando haces zoom, se ve feo

Si te estás preguntando, ¿cuál es la mejor manera de dibujar un punto , iría con un rectángulo lleno? Puedes ver mi jsperf aquí con pruebas de comparación


Por motivos de rendimiento, no dibuje un círculo si puede evitarlo. Simplemente dibuja un rectángulo con un ancho y alto de uno:

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


Si planea dibujar una gran cantidad de píxeles, es mucho más eficiente utilizar los datos de imagen del lienzo para hacer el dibujo de píxeles.

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 puedes usarlo de esta manera:

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

Para obtener más información, puede echar un vistazo a esta publicación de blog de Mozilla: http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/