【问题标题】:Html canvas draw smooth lines with bezier curveHtml画布用贝塞尔曲线绘制平滑线条
【发布时间】:2022-09-27 23:17:46
【问题描述】:

我的画布线条有一个问题是,每当我尝试绘制线条时,它们并不平滑,线条看起来像一堆相互连接的小线条,我尝试使用 quadraticCurveTo 找到解决方案并计算中点线

const draw = (e) => {
    if (!isPainting) {
        return;
    }
    const x = e.pageX - canvasOffsetX;
    const y = e.pageY - canvasOffsetY;
    points.push({ x: x, y: y });
    ctx.lineWidth = lineWidth;
    ctx.lineCap = \'round\';
    ctx.lineJoin = \'round\';
    ctx.globalAlpha = opacity;
    ctx.imageSmoothingQuality = \"high\";
    ctx.beginPath();

    if (points.length === 1) {
        ctx.moveTo(x, y);
    } else {
        for (let i = 1, len = points.length; i < len; i++) {
            let xc = (points[i].x + points[i + 1].x) / 2;
            let yc = (points[i].y + points[i + 1].y) / 2;
            ctx.quadraticCurveTo(points[i].x, points[i].y, xc, yc);

        }

        ctx.stroke();

    }
};

这种方法效果很好,但是在鼠标启动后或计算完成后出现线条,这不是最好的方法,我尝试在鼠标启动后更改线条之前画线,但它也不起作用

我能找到的唯一相对答案是这个codepen: https://codepen.io/kangax/pen/kyYrdX

但它的问题是我必须在绘制新线之前清除画布并且我希望所有的图纸都存在

    标签: javascript canvas html5-canvas


    【解决方案1】:

    可能为时已晚,但这是通过编辑您提到的代码笔的解决方案。

    1. 您需要在 mousedown 事件和 将其保存到全局变量

    2. 清除画布后,您需要将该快照粘贴到 帆布

      function midPointBtw(p1, p2) {
        return {
          x: p1.x + (p2.x - p1.x) / 2,
          y: p1.y + (p2.y - p1.y) / 2
        };
      }
      
      var el = document.getElementById('c');
      var ctx = el.getContext('2d');
      
      ctx.lineWidth = 10;
      ctx.lineJoin = ctx.lineCap = 'round';
      
      var isDrawing, points = [ ];
      var snapshot;
      el.onmousedown = function(e) {
       snapshot = ctx.getImageData(0, 0, el.width, el.height);
      
        isDrawing = true;
        points.push({ x: e.clientX, y: e.clientY });
      };
      
      el.onmousemove = function(e) {
        if (!isDrawing) return;
        
        points.push({ x: e.clientX, y: e.clientY });
      
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
         ctx.putImageData(snapshot, 0, 0);
        var p1 = points[0];
        var p2 = points[1];
        
        ctx.beginPath();
        ctx.moveTo(p1.x, p1.y);
        console.log(points);
      
        for (var i = 1, len = points.length; i < len; i++) {
          // we pick the point between pi+1 & pi+2 as the
          // end point and p1 as our control point
          var midPoint = midPointBtw(p1, p2);
          ctx.quadraticCurveTo(p1.x, p1.y, midPoint.x, midPoint.y);
          p1 = points[i];
          p2 = points[i+1];
        }
        // Draw last line as a straight line while
        // we wait for the next point to be able to calculate
        // the bezier control point
        ctx.lineTo(p1.x, p1.y);
        ctx.stroke();
      };
      
      el.onmouseup = function() {
        isDrawing = false;
        points.length = 0;
      };
      canvas { border: 1px solid #ccc }
      &lt;canvas id="c" width="500" height="300"&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-26
      相关资源
      最近更新 更多