首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用HTML5画布创建软笔触边缘

如何使用HTML5画布创建软笔触边缘
EN

Stack Overflow用户
提问于 2012-01-25 21:50:43
回答 4查看 5.5K关注 0票数 7

我正在使用HTML5 canvas创建一个绘图应用程序。

https://github.com/homanchou/sketchyPad

我可以使用rgba来控制我的线条笔触的不透明度,但是我如何实现一个柔和的羽毛笔刷边缘与一个坚硬的圆形边缘呢?

EN

回答 4

Stack Overflow用户

发布于 2012-01-31 17:51:02

三种可能的解决方案:

  1. 您可以将线条写入屏幕外的画布,应用模糊过滤器,然后将结果绘制到可见的画布中。
  2. 如果只使用直线段,则可以对每个线段使用线性渐变。与线段的方向相比,渐变的方向必须为90“角。
  3. 在同一位置多次绘制相同的线条。首先使用全宽和较小的alpha。然后减小宽度并增加alpha。

对每个线段使用线性渐变的示例:

http://jsfiddle.net/chdh/MmYAt/

代码语言:javascript
运行
AI代码解释
复制
function drawSoftLine(x1, y1, x2, y2, lineWidth, r, g, b, a) {
   var lx = x2 - x1;
   var ly = y2 - y1;
   var lineLength = Math.sqrt(lx*lx + ly*ly);
   var wy = lx / lineLength * lineWidth;
   var wx = ly / lineLength * lineWidth;
   var gradient = ctx.createLinearGradient(x1-wx/2, y1+wy/2, x1+wx/2, y1-wy/2);
      // The gradient must be defined accross the line, 90° turned compared
      // to the line direction.
   gradient.addColorStop(0,    "rgba("+r+","+g+","+b+",0)");
   gradient.addColorStop(0.43, "rgba("+r+","+g+","+b+","+a+")");
   gradient.addColorStop(0.57, "rgba("+r+","+g+","+b+","+a+")");
   gradient.addColorStop(1,    "rgba("+r+","+g+","+b+",0)");
   ctx.save();
   ctx.beginPath();
   ctx.lineWidth = lineWidth;
   ctx.strokeStyle = gradient;
   ctx.moveTo(x1, y1);
   ctx.lineTo(x2, y2);
   ctx.stroke();
   ctx.restore(); }

通过减小宽度和增加alpha多次绘制一条线的示例:

http://jsfiddle.net/chdh/RmtxL/

代码语言:javascript
运行
AI代码解释
复制
function drawSoftLine(x1, y1, x2, y2, lineWidth, r, g, b, a) {
   ctx.save();
   var widths = [1   , 0.8 , 0.6 , 0.4 , 0.2  ];
   var alphas = [0.2 , 0.4 , 0.6 , 0.8 , 1    ];
   var previousAlpha = 0;
   for (var pass = 0; pass < widths.length; pass++) {
      ctx.beginPath();
      ctx.lineWidth = lineWidth * widths[pass];
      var alpha = a * alphas[pass];
      // Formula: (1 - alpha) = (1 - deltaAlpha) * (1 - previousAlpha)
      var deltaAlpha = 1 - (1 - alpha) / (1 - previousAlpha)
      ctx.strokeStyle = "rgba(" + r + "," + g + "," + b + "," + deltaAlpha + ")";
      ctx.moveTo(x1, y1);
      ctx.lineTo(x2, y2);
      ctx.stroke();
      previousAlpha = alpha; }
   ctx.restore(); }
票数 7
EN

Stack Overflow用户

发布于 2012-01-25 21:57:12

我敢肯定这取决于你使用的浏览器。上次我检查过了(不久前--可能已经改变了)火狐和Chrome不能消除边缘锯齿,而IE9可以。

票数 1
EN

Stack Overflow用户

发布于 2016-03-09 09:12:34

您可以使用css过滤器来模糊画布。使用SVG rasterization trick可以做到这一点。下面是你如何做到这一点:

  1. 制作两个画布,一个在另一个画布上。其中一个称为«Target»,另一个称为«Buffer»。Buffer是你在上面画的,Target是画布的结果。
  2. css-filter: blur(px)应用到Buffer画布上,这样用户可以立即看到模糊的预览。
  3. 这是有趣的部分。在每个笔划上(即鼠标向上),光栅化缓冲区画布,将图像放入<svg><foreignObject></foreignObject></svg>,应用相同的CSS过滤器,光栅化SVG,并将光栅化的SVG放在目标画布上。这是gist with code example.
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9010835

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档