使用context.moveTo()和context.lineTo()函数在HTML5画布上绘制一条线非常简单.
我不太确定是否可以绘制一个点,即单个像素的颜色.lineTo函数不会绘制单个像素线(显然).
有没有办法做到这一点?
HoL*_*ieR 144
如果您计划绘制大量像素,则使用画布的图像数据进行像素绘制会更有效.
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);
}
Run Code Online (Sandbox Code Playgroud)
你可以这样使用它:
drawPixel(1, 1, 255, 0, 0, 255);
drawPixel(1, 2, 255, 0, 0, 255);
drawPixel(1, 3, 255, 0, 0, 255);
updateCanvas();
Run Code Online (Sandbox Code Playgroud)
有关更多信息,您可以查看此Mozilla博客文章:http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/
Sim*_*ris 131
出于性能原因,如果可以避免,请不要绘制圆圈.只需绘制一个宽度和高度为1的矩形:
ctx.fillRect(10,10,1,1); // fill in the pixel at (10,10)
Run Code Online (Sandbox Code Playgroud)
Sal*_*ali 39
这看起来很奇怪,但HTML5支持绘制线条,圆形,矩形和许多其他基本形状,它没有任何适合绘制基本点的东西.唯一的方法是用你拥有的任何东西来模拟一个点.
所以基本上有3种可能的解决方案:
他们每个人都有自己的缺点.
线
function point(x, y, canvas){
canvas.beginPath();
canvas.moveTo(x, y);
canvas.lineTo(x+1, y+1);
canvas.stroke();
}
Run Code Online (Sandbox Code Playgroud)
请记住,我们正在向东南方向前进,如果这是边缘,则可能存在问题.但你也可以在任何其他方向画画.
长方形
function point(x, y, canvas){
canvas.strokeRect(x,y,1,1);
}
Run Code Online (Sandbox Code Playgroud)
或者以更快的方式使用fillRect,因为渲染引擎只会填充一个像素.
function point(x, y, canvas){
canvas.fillRect(x,y,1,1);
}
Run Code Online (Sandbox Code Playgroud)
圈
圆圈的一个问题是引擎更难渲染它们
function point(x, y, canvas){
canvas.beginPath();
canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
canvas.stroke();
}
Run Code Online (Sandbox Code Playgroud)
你可以用填充实现与矩形相同的想法.
function point(x, y, canvas){
canvas.beginPath();
canvas.arc(x, y, 1, 0, 2 * Math.PI, true);
canvas.fill();
}
Run Code Online (Sandbox Code Playgroud)
所有这些解决方案的问题:
如果你想知道,绘制点的最佳方法是什么,我会选择填充矩形.你可以在这里用比较测试看到我的jsperf
小智 6
在我的Firefox中,这个技巧有效:
function SetPixel(canvas, x, y)
{
canvas.beginPath();
canvas.moveTo(x, y);
canvas.lineTo(x+0.4, y+0.4);
canvas.stroke();
}
Run Code Online (Sandbox Code Playgroud)
屏幕上看不到小偏移,但强制渲染引擎实际绘制点.
小智 6
上面的说法是“如果您打算绘制很多像素,则使用画布的图像数据进行像素绘制会更有效率”,这似乎是错误的-至少对于Chrome 31.0.1650.57 m或更高在您对“很多像素”的定义上。我本来希望直接对相应的帖子发表评论-但不幸的是我还没有足够的stackoverflow点:
我认为我正在绘制“很多像素”,因此我首先按照各自的建议进行了很好的测量,后来我为每个绘制的点将实现更改为简单的ctx.fillRect(..),请参见http:// www。 wothke.ch/webgl_orbittrap/Orbittrap.htm
有趣的是,在我的示例中,愚蠢的ctx.fillRect()实现实际上至少是基于ImageData的双缓冲方法的两倍。
至少对于我的情况,似乎内置的ctx.getImageData / ctx.putImageData确实慢得令人难以置信。(知道基于ImageData的方法可能领先之前需要触摸的像素百分比会很有趣。)
结论:如果需要优化性能,则必须分析您的代码并根据您的发现采取行动。
| 归档时间: |
|
| 查看次数: |
123467 次 |
| 最近记录: |