HTML5 Canvas 和线宽

标签 html canvas

我正在 Canvas 上绘制折线图。线条画得很好。图形被缩放,每个线段都被绘制,颜色都可以,等等。我唯一的问题是视觉上线宽变化。它几乎就像书法笔的 Nib 。如果笔画向上,则线条较细,如果笔画水平,则线条较粗。

我的线条粗细是恒定的,我的 strokeStyle 设置为 black。我没有看到 Canvas 的任何其他属性会影响如此变化的线宽,但肯定有。

最佳答案

Javascript:

var badCanvas = document.getElementById("badCanvas"),
    goodCanvas = document.getElementById("goodCanvas"),
    bCtx = badCanvas.getContext("2d"),
    gCtx = goodCanvas.getContext("2d");

badCanvas.width = goodCanvas.width = badCanvas.height = goodCanvas.height = 300;

// Line example where the lines are blurry weird ect.
// Horizontal
bCtx.beginPath();
bCtx.moveTo(10,10);
bCtx.lineTo(200,10);
bCtx.stroke();
//Verticle
bCtx.beginPath();
bCtx.moveTo(30,30);
bCtx.lineTo(30,200);
bCtx.stroke();

// Proper way to draw them so they are "clear"
//Horizontal
gCtx.beginPath();
gCtx.moveTo(10.5,10.5);
gCtx.lineTo(200.5,10.5);
gCtx.stroke();
//Verticle
gCtx.beginPath();
gCtx.moveTo(30.5,30);
gCtx.lineTo(30.5,200);
gCtx.stroke();


// Change the line width
bCtx.lineWidth = 4;
gCtx.lineWidth = 4;


// Line example where the lines are blurry weird ect.
// Horizontal
bCtx.beginPath();  
bCtx.moveTo(10,20.5);
bCtx.lineTo(200,20.5);
bCtx.stroke();
//Verticle
bCtx.beginPath()
bCtx.moveTo(50.5,30);
bCtx.lineTo(50.5,200);
bCtx.stroke();

// Proper way to draw them so they are "clear"
//Horizontal
gCtx.beginPath();
gCtx.moveTo(10,20);
gCtx.lineTo(200,20);
gCtx.stroke();
//Verticle
gCtx.beginPath();
gCtx.moveTo(50,30);
gCtx.lineTo(50,200);
gCtx.stroke();

HTML:

<h2>BadCanvas</h2>
<canvas id="badCanvas"></canvas>
<h2>Good Canvas</h2>
<canvas id="goodCanvas"></canvas>

CSS:

canvas{border:1px solid  blue;}

Live Demo

我的现场演示基本上只是重现了 MDN 所说的内容。对于偶数笔划宽度,您可以使用整数作为坐标,对于奇数笔划宽度,您希望使用 .5 以获得正确填充像素的清晰线条。

MDN Image

来自 MDN Article

If you consider a path from (3,1) to (3,5) with a line thickness of 1.0, you end up with the situation in the second image. The actual area to be filled (dark blue) only extends halfway into the pixels on either side of the path. An approximation of this has to be rendered, which means that those pixels being only partially shaded, and results in the entire area (the light blue and dark blue) being filled in with a color only half as dark as the actual stroke color. This is what happens with the 1.0 width line in the previous example code.

To fix this, you have to be very precise in your path creation. Knowing that a 1.0 width line will extend half a unit to either side of the path, creating the path from (3.5,1) to (3.5,5) results in the situation in the third image — the 1.0 line width ends up completely and precisely filling a single pixel vertical line.

关于HTML5 Canvas 和线宽,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7530593/

相关文章:

reactjs - react typescript : Type 'null' is not assignable to type 'CanvasRenderingContext2D'

WPF 可调整大小的 Canvas

html - 减少 "subscribe"按钮的宽度

javascript - 从中心动画/显示内容

html - 编辑 HTML 文件,发送 HTML Email iOS

javascript - 页面加载时 Iframe 的随机 URL

html - 用线条设计标题

javascript - 使用 1 个按钮获取 2 个 Canvas 图像

javascript - HTML5 Canvas 调整大小(缩小)图像质量?

javascript - Fabric.js 中的多个 Canvas (页面)