如何在HTML5画布绘图应用程序中创建圆形“画笔笔尖”?

时间:2011-08-12 21:31:07

标签: html5 canvas drawing

我正在使用HTML5 lineTo,但任何大于1的笔划都会在线条上产生方形角(笔划垂直于您绘制的线条的路径)。我想创建一个圆形画笔笔尖,类似于http://muro.deviantart.com

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

通过设置线帽可以使角变圆。

ctx.lineCap = "round"

您还可以对整个线应用贝塞尔曲线,以创建更平滑的整体线,对于线P' 0 中的每个点,...,P' n + 1 ,应用方程P' k =(k /(n + 1))P k-1 +(1-(k /(n + 1) )))P k [注意:您可以通过设置阈值来选择应用贝塞尔曲线平滑的点,可能在P 之间的角度n 和P n + 1 ]

将这两种技术与标准框模糊相结合,可以为线条提供更加流畅的线条。

修改

据我所知,实际上有很多方法可以做到这一点 - 你使用它完全取决于你。我将给你一个例子,让你决定:假设你有一个从起点p m (mousedown)到端点(mouseup)的路径p n 。该路径由子路径(由miters连接的点)组成。我们可以通过lineTo()和stroke()正常绘制从p0到p1的上下文路径。仅仅通过观察控制台输出,子路径连接的点是mousemove事件触发。按顺序在数组中记录这些点。

当然,如果我们将它绘制到主上下文中,我们在删除它时会遇到问题,因此应该对缓冲区上下文(例如,另一个canvas元素)执行此操作。清除缓冲区,我们使用斜点的点来计算曲线。 bezierCurveTo打印立方函数(B(t)=(1-t) 3 P 0 +3(1-t) 2 P <子> 1 +3(1-t)的吨 2 P <子> 2 + T 3 P <子> 3 ,t∈[0,1]。逐步通过你的数组(想想循环)用这些点重新计算直线,将曲线从P 0 更新为P n-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();
}

同样,这就是我所看到的 - 别人可能会有一个完全不同的,我肯定会有更好的解释。我正在尝试撕掉我已经完成的大量事情,然后快速将它们与一些新代码放在一起,以便给你一些想法。