【发布时间】:2011-10-26 04:01:30
【问题描述】:
我正在使用 HTML5 lineTo,但任何大于 1 的笔划都会在线条上创建方形的角(笔划垂直于您绘制的线条的路径延伸)。我想创建一个圆形画笔笔尖,类似于http://muro.deviantart.com。
有什么想法吗?
【问题讨论】:
-
你看过
ctx.lineCap- 也许这就是你所追求的。
我正在使用 HTML5 lineTo,但任何大于 1 的笔划都会在线条上创建方形的角(笔划垂直于您绘制的线条的路径延伸)。我想创建一个圆形画笔笔尖,类似于http://muro.deviantart.com。
有什么想法吗?
【问题讨论】:
ctx.lineCap - 也许这就是你所追求的。
可以通过设置线帽来圆角。
ctx.lineCap = "round"
您还可以将贝塞尔曲线应用于整体线条以创建更平滑的整体线条,对于线条中的每个点 P'0, ..., P'n + 1 ,应用等式 P'k = (k/(n+1))Pk-1+(1-(k/(n+1 )))Pk[注意:您最好通过设置阈值来选择应用贝塞尔曲线平滑的点,可能是 P 之间的角度n 和 Pn+1]
将这两种技术与线条本身的标准框模糊相结合,将使您的线条看起来更加平滑。
编辑
据我所知,实际上有很多方法可以做到这一点——您使用哪种方法完全取决于您。我给你一个例子,让你决定:假设你有一条从起点 pm (mousedown) 到终点 (mouseup) pn 的路径.该路径由子路径(由斜接连接的点)组成。我们可以像往常一样使用 lineTo() 和 stroke() 绘制从 p0 到 p1 的上下文路径。仅从控制台输出来看,子路径连接的点就是 mousemove 事件触发。将这些点按顺序记录在一个数组中。
当然,如果我们将它绘制到主上下文中,我们会遇到删除它的问题,因此应该对缓冲区上下文(例如,附加的画布元素)执行此操作。缓冲区被清除,我们使用斜接点来计算曲线。 bezierCurveTo 打印三次函数 (B(t) = (1-t)3P0+3(1-t)2P1+3(1-t)t2P2+t3P3, t ∈ [0,1]. 遍历你的数组(想想循环)用这些点重新计算线,将曲线从 P0 更新到 Pn-3.(快速进行头脑计算。您可能需要考虑这个端点。所有这些都取决于您使用的弧形方程)。
所以让我看看我能不能用这个做点什么......我没有测试它,所以我保证有错误。
// Assume:
// bfr = buffer context.
// ctx = main context.
// md = boolean value for mousedown
// pts = []; <-- already contains lp (below) at pts[0];
// We've also recorded Pm in associative array lp [last point]
// Draw is fired on mousemove. Mousemove records a current point in associative array cp
draw = function() {
if(md) {
bfr.beginPath();
bfr.moveTo(lp.x-.5, lp.y-.5);
bfr.lineTo(cp.x-.5, cp.y-.5);
pts.push({cp.x, cp.y});
bfr.stroke();
}
}
// Optionally, you could make this function recursive.
// This assumes that you want to estimate the curve based on the whole line.
bezier = function(pts) {
ctx.beginPath();
ctx.moveTo(pts[0].x, pts[0].y);
for( var i = 0; i < pts.length - 3; i++ ) {
ctx.bezierCurveTo( pts[i+1].x, pts[i+1].y, pts[i+2].x, pts[i+2].y, pts[i+3].x, pts[i+3].y);
}
ctx.stroke();
}
再一次,这就是我所看到的——其他人可能有完全不同的看法,我相信会有更好的解释。我正在尝试将我所做的大量事情撕掉,并快速将它们与一些新代码组合在一起,以便为您提供一些想法。
【讨论】:
mousemove 触发的点进行采样,确定三个点之间的角度以检查采样点是否存在显着差异,如果存在则标记它,然后使用它来应用曲线。我会将标记点数组传递给函数以执行评估。始终以 mousedown 和 mouseup 开头,分别为 0 和 n+1。