画布上的漂亮椭圆?

时间:2013-01-20 12:42:11

标签: javascript html5 canvas

是否有可能创建具有更好笔画的椭圆/椭圆,而这些笔画没有“模糊”边框,类似于:

我可以以某种方式在椭圆形周围创建更清晰的笔划线,还是我必须忍受那个“模糊”边框? enter image description here

3 个答案:

答案 0 :(得分:3)

!你能行的 !通过后处理:

1)使用globalCompositeOperation:

编辑:    是的,但不是:至少在Chrome上,'destination-in'不会 符合规范:源用于计算目的地 颜色,所以我们不能用阴影颜色单色。
(我尝试了JSBin:http://jsbin.com/ecipiq/4/

OR

2)使用getImageData和performance Array:

  • 在临时画布中绘制边框
  • 画布的getImageData
  • 获取基础数据的Uint32Array或Uint8Array视图
  • 在数组内线性循环:if value>阈值将其设置为边框颜色
  • 在目标画布上绘制椭圆的填充
  • 将putImageData放在目标画布上。

哪一个?

  • 第二个不需要globalCompositeOperation工作 但是在大多数浏览器上(全部?)get / put ImageData都很慢,这个事实 单独可能使此解决方案无效 好消息是你可以精确地决定如何解除反抗。

其他StackOverflow成员可能对此有所了解。

任何这些解决方案都会比手写的非别名更快  椭圆函数。

第一个解决方案的有用链接:
http://www.html5rocks.com/en/tutorials/webgl/typed_arrays/

备注让你更快地开始:
您可以使用以下命令在ImageData上获取UInt32Array视图:

var myGetImageData = myTempCanvas.getImageData(0,0,sizeX, sizeY);
sourceBuffer32     = new UInt32Array(myGetImageData.data.buffer);

然后sourceBuffer32 [i]包含红色,绿色,蓝色和透明度 无符号32位int。将其与0进行比较,以了解像素是否为非黑色(!=(0,0,0,0))

或者你可以使用Uint8Array视图更加精确:

var myGetImageData = myTempCanvas.getImageData(0,0,sizeX, sizeY);
sourceBuffer8     = new Uint8Array(myGetImageData.data.buffer);

如果你只处理灰色阴影,那么R = G = B,所以注意

sourceBuffer8[4*i]>Threshold

您可以使用UInt32Array视图一次将第i个像素设置为黑色:

sourceBuffer32[i]=(255<<24)||(255<<16)||(255<<8);

你肯定能够弄清楚如何处理这个例子中的灰色/黑色以外的其他颜色。

答案 1 :(得分:2)

简短的回答是不,抱歉!

规范没有评论浏览器必须使用的抗锯齿方法(或不公开),因此它们在浏览器之间是完全不同的。不同版本的Chrome(特别是如果您使用Chrome测试版或开发人员频道)会一直触发这一点。

有些关于在规范中对此进行编码的讨论之前已经发生过,但是没有采取任何行动,除了现在可以选择关闭图像平滑(上下文的imageSmoothingEnabled属性)的图像。但这绝不适用于路径。

遗憾的是,一种解决方案只适用于最狭窄的环境:如果你的省略号是固定的,就是在Firefox中创建它们(可以说是具有最流畅抗锯齿的浏览器)并从中生成图像,然后用图像绘制所有的浏览器。

简而言之,如果您想在所有浏览器中使用像素相同的形状,则必须使用图像,目前没有别的办法。

答案 2 :(得分:2)

是的,你可以!这是调用context.stroke() 25次而不是仅调用一次的结果:

non-blurry ellipse

为了比较,这是原始的:

blurry ellipse