Html 在 HTML5 画布上画一个点
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7812514/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Drawing a dot on HTML5 canvas
提问by infiniteloop
Drawing a line on the HTML5 canvas is quite straightforward using the context.moveTo()
and context.lineTo()
functions.
使用context.moveTo()
和context.lineTo()
函数在 HTML5 画布上画一条线非常简单。
I'm not quite sure if it's possible to draw a dot i.e. color a single pixel. The lineTo function wont draw a single pixel line (obviously).
我不太确定是否可以绘制一个点,即为单个像素着色。lineTo 函数不会绘制单个像素线(显然)。
Is there a method to do this?
有没有办法做到这一点?
回答by HoLyVieR
If you are planning to draw a lot of pixel, it's a lot more efficient to use the image data of the canvas to do pixel drawing.
如果你打算绘制大量像素,使用画布的图像数据进行像素绘制会效率更高。
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);
}
Then, you can use it in this way :
然后,您可以这样使用它:
drawPixel(1, 1, 255, 0, 0, 255);
drawPixel(1, 2, 255, 0, 0, 255);
drawPixel(1, 3, 255, 0, 0, 255);
updateCanvas();
For more information, you can take a look at this Mozilla blog post : http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/
有关更多信息,您可以查看此 Mozilla 博客文章:http: //hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/
回答by Simon Sarris
For performance reasons, don't draw a circle if you can avoid it. Just draw a rectangle with a width and height of one:
出于性能原因,如果可以避免,请不要绘制圆圈。只需绘制一个宽度和高度为 1 的矩形:
ctx.fillRect(10,10,1,1); // fill in the pixel at (10,10)
回答by Salvador Dali
It seems strange, but nonetheless HTML5 supports drawing lines, circles, rectangles and many other basic shapes, it does not have anything suitable for drawing the basic point. The only way to do so is to simulate a point with whatever you have.
看起来很奇怪,但 HTML5 支持绘制线条、圆形、矩形等许多基本形状,它没有任何适合绘制基本点的东西。这样做的唯一方法是用你拥有的任何东西模拟一个点。
So basically there are 3 possible solutions:
所以基本上有3种可能的解决方案:
- draw point as a line
- draw point as a polygon
- draw point as a circle
- 将点画成一条线
- 将点绘制为多边形
- 将点画成一个圆圈
Each of them has their drawbacks.
他们每个人都有自己的缺点。
Line
线
function point(x, y, canvas){
canvas.beginPath();
canvas.moveTo(x, y);
canvas.lineTo(x+1, y+1);
canvas.stroke();
}
Keep in mind that we are drawing to South-East direction, and if this is the edge, there can be a problem. But you can also draw in any other direction.
请记住,我们正在向东南方向绘制,如果这是边缘,则可能会有问题。但是您也可以向任何其他方向绘制。
Rectangle
长方形
function point(x, y, canvas){
canvas.strokeRect(x,y,1,1);
}
or in a faster way using fillRect because render engine will just fill one pixel.
或者以更快的方式使用 fillRect 因为渲染引擎只会填充一个像素。
function point(x, y, canvas){
canvas.fillRect(x,y,1,1);
}
Circle
圆圈
One of the problems with circles is that it is harder for an engine to render them
圆圈的问题之一是引擎更难渲染它们
function point(x, y, canvas){
canvas.beginPath();
canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
canvas.stroke();
}
the same idea as with rectangle you can achieve with fill.
与使用填充可以实现的矩形相同的想法。
function point(x, y, canvas){
canvas.beginPath();
canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
canvas.fill();
}
Problems with all these solutions:
所有这些解决方案的问题:
- it is hard to keep track of all the points you are going to draw.
- when you zoom in, it looks ugly
- 很难跟踪您要绘制的所有点。
- 当你放大时,它看起来很丑
If you are wondering, what is the best way to draw a point, I would go with filled rectangle. You can see my jsperf here with comparison tests
如果您想知道绘制点的最佳方法是什么,我会使用实心矩形。你可以在这里看到我的jsperf 对比测试
回答by milet
In my Firefox this trick works:
在我的 Firefox 中,这个技巧有效:
function SetPixel(canvas, x, y)
{
canvas.beginPath();
canvas.moveTo(x, y);
canvas.lineTo(x+0.4, y+0.4);
canvas.stroke();
}
Small offset is not visible on screen, but forces rendering engine to actually draw a point.
屏幕上看不到小偏移,但会强制渲染引擎实际绘制一个点。
回答by wothke
The above claim that "If you are planning to draw a lot of pixel, it's a lot more efficient to use the image data of the canvas to do pixel drawing" seems to be quite wrong - at least with Chrome 31.0.1650.57 m or depending on your definition of "lot of pixel". I would have preferred to comment directly to the respective post - but unfortunately I don't have enough stackoverflow points yet:
上面声称“如果您打算绘制大量像素,使用画布的图像数据进行像素绘制会更有效率”似乎是完全错误的 - 至少在 Chrome 31.0.1650.57 m 或取决于关于“大量像素”的定义。我宁愿直接对相应的帖子发表评论 - 但不幸的是我还没有足够的 stackoverflow 点:
I think that I am drawing "a lot of pixels" and therefore I first followed the respective advice for good measure I later changed my implementation to a simple ctx.fillRect(..) for each drawn point, see http://www.wothke.ch/webgl_orbittrap/Orbittrap.htm
我认为我正在绘制“很多像素”,因此我首先遵循了各自的建议以获得良好的度量,后来我将我的实现更改为每个绘制点的简单 ctx.fillRect(..),请参阅http://www. wothke.ch/webgl_orbittrap/Orbittrap.htm
Interestingly it turns out the silly ctx.fillRect() implementation in my example is actually at least twice as fast as the ImageData based double buffering approach.
有趣的是,我的示例中愚蠢的 ctx.fillRect() 实现实际上至少是基于 ImageData 的双缓冲方法的两倍。
At least for my scenario it seems that the built-in ctx.getImageData/ctx.putImageData is in fact unbelievably SLOW. (It would be interesting to know the percentage of pixels that need to be touched before an ImageData based approach might take the lead..)
至少在我的情况下,似乎内置的 ctx.getImageData/ctx.putImageData 实际上慢得令人难以置信。(在基于 ImageData 的方法可能领先之前知道需要触摸的像素百分比会很有趣。)
Conclusion: If you need to optimize performance you have to profile YOUR code and act on YOUR findings..
结论:如果您需要优化性能,您必须分析您的代码并根据您的发现采取行动。
回答by by0
This should do the job
这应该可以完成工作
//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();