代码之家  ›  专栏  ›  技术社区  ›  user889030

如何在画布上绘制流程图文档形状?

  •  0
  • user889030  · 技术社区  · 6 年前

    正在尝试绘制流程图文档形状( https://i.imgur.com/ZfWDDfs.png )在画布上,我已经做了一部分,但很难处理较低的曲线,因为它在一个位置显示正常,但当我改变x-y坐标时,曲线会受到影响,所以我想知道如何正确地在其中绘制曲线,使其在坐标改变后保持不变。

    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    
    // var x = 150, y = 150, w = 350, h = 350;  // display ok
    var x = 50, y = 50, w = 350, h = 350;  // display not ok
    
     ctx.lineWidth = 10;
     ctx.beginPath();
     ctx.lineJoin="round";
    // draw one horizontal and two vertical lines
     ctx.moveTo(x, y);
     ctx.lineTo((x + w)+(w/4), y);
     ctx.lineTo((x + w)+(w/4) , y + h/1.3);
    
     ctx.moveTo(x, y);
     ctx.lineTo(x, y + h);
    
    // bottom curve .. problem start here
    ctx.quadraticCurveTo(x,h + (h/1.2), (x + w/2) ,h + h/4);
    ctx.lineTo((x + w)+(w/4), y+h/1.3);
    ctx.stroke();
    

    此代码使用x=50和y=50:

    let drawChart = function(ctx, points) {
      ctx.moveTo((points[0].x), points[0].y);
    
      for (var i = 0; i < points.length - 1; i++) {
        // Draw point
        //   ctx.arc(points[i].x, points[i].y, 2, 0, Math.PI * 2, false);
    
        var x_mid = (points[i].x + points[i + 1].x) / 2;
        var y_mid = (points[i].y + points[i + 1].y) / 2;
        var cp_x1 = (x_mid + points[i].x) / 2;
        var cp_y1 = (y_mid + points[i].y) / 2;
        var cp_x2 = (x_mid + points[i + 1].x) / 2;
        var cp_y2 = (y_mid + points[i + 1].y) / 2;
    
        ctx.quadraticCurveTo(cp_x1, points[i].y, x_mid, y_mid);
        ctx.quadraticCurveTo(cp_x2, points[i + 1].y, points[i + 1].x, points[i + 1].y);
        ctx.stroke();
      }
      //   ctx.arc(points[points.length - 1].x, points[points.length - 1].y, 2, 0, Math.PI * 2, false)
      //   ctx.stroke();
    }
    
    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    
    //var x = 150, y = 150, w = 350, h = 350;   // ok
    
    var x = 50,
      y = 50,
      w = 350,
      h = 350; // not ok
    
    ctx.lineWidth = 10;
    
    ctx.beginPath();
    ctx.lineJoin = "round";
    ctx.moveTo(x, y);
    ctx.lineTo((x + w) + (w / 4), y);
    ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
    ctx.moveTo(x, y);
    ctx.lineTo(x, y + h);
    // var points = [{x:x,y:y + h},{x:(x + w/2),y:h + h/5},{x:(x + w)+(w/4),y:h/1.3 }] 
    // var points = [{x:x,y:y + h},{x:(x + w/3),y:h + h/2},{x:(x + w/1.2),y:h + h/4},{x:(x + w)+(w/4),y:h + h/5}] 
    //drawChart(ctx,points);
    ctx.quadraticCurveTo(x, h + (h / 1.2), (x + w / 2), h + h / 4);
    // ctx.quadraticCurveTo((x + w/2),h ,  (x + w)+(w/4) , h + h/5 );
    ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
    //  ctx.closePath();
    
    ctx.stroke();
    
    //	ctx.fill();
    <canvas id="myCanvas" width="800" height="600" style="border:1px solid #d3d3d3;">
    Your browser does not support the HTML5 canvas tag.</canvas>

    http://jsfiddle.net/0da2e869/

    1 回复  |  直到 6 年前
        1
  •  1
  •   user2226755    6 年前

    你必须使用:

    ctx.quadraticCurveTo(x, y + h * 1.6, x + w / 2, y + h);
    

    第一个和第二个参数是在网格上的位置。

    ctx.quadraticCurveTo(cpx, cpy, x, y);
    

    注意:为了提高你的画画效果 ctx.lineCap = "round"; . ;)

    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    
    drawIt(150, 150, 350, 350); // ok
    ctx.strokeStyle = "red";
    drawIt(50, 50, 350, 350); // not ok
    
    function drawIt(x, y, w, h) {
      ctx.lineWidth = 10;
    
      ctx.beginPath();
      ctx.lineJoin = "round";
      ctx.lineCap = "round"; //<========== lineCap
      ctx.moveTo(x, y);
      ctx.lineTo((x + w) + (w / 4), y);
      ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
      ctx.moveTo(x, y);
      ctx.lineTo(x, y + h);
      ctx.quadraticCurveTo(x, y + h * 1.6, x + w / 2, y + h);
      ctx.lineTo((x + w) + (w / 4), y + h / 1.3);
    
      ctx.stroke();
    }
    canvas {
      /* Focus on the "not ok" */
      transform-origin: top left;
      transform: scale(.25);
      transition:1s;
    }
    
    body:hover canvas {
      /* Focus on the "not ok" */
      transform-origin: top left;
      transform: none;
    }
    <canvas id="myCanvas" width="800" height="800" style="border:1px solid #d3d3d3;"></canvas>