将 SVG 路径转换为 ​​canvas html5

Transform SVG path to canvas html5

这里我有一些制作 svg 路径的代码:

http://jsbin.com/gazecasagi/1/edit?html,output

 <html>
      <head>

        <script>
    function draw() {
      var polygons = [[{"X":22,"Y":59.45},{"X":136,"Y":66},{"X":170,"Y":99},{"X":171,"Y":114},{"X":183,"Y":125},{"X":218,"Y":144},{"X":218,"Y":165},{"X":226,"Y":193},{"X":254,"Y":195},{"X":283,"Y":195},{"X":292,"Y":202},{"X":325,"Y":213},{"X":341,"Y":134},{"X":397,"Y":245},{"X":417,"Y":548}]]; 
      var scale = 1000;
      reverse_copy(polygons);
      polygons = scaleup(polygons, scale);
      var cpr = new ClipperLib.Clipper();
      var delta = 20;
      var joinType = ClipperLib.JoinType.jtRound;
      var miterLimit = 2;
      var AutoFix = true;
      var svg, offsetted_polygon,
      cont = document.getElementById('svgcontainer');
      offsetted_polygon = cpr.OffsetPolygons(polygons, delta * scale, joinType, miterLimit, AutoFix);
      //console.log(JSON.stringify(offsetted_polygon));

      // Draw red offset polygon
      svg = '<svg style="margin-top:10px;margin-right:10px;margin-bottom:10px;background-color:#dddddd" width="800" height="600">';
      svg += '<path stroke="red" fill="red" stroke-width="2" stroke-opacity="0.6" fill-opacity="0.2" d="' + polys2path(offsetted_polygon, scale) + '"/>';

      //Draw blue polyline
      svg += '<path stroke="blue" stroke-width="1" d="' + polys2path(polygons, scale) + '"/>';
      svg += '</svg>';

          cont.innerHTML += svg;
    }
    // helper function to scale up polygon coordinates
    function scaleup(poly, scale) {
      var i, j;
      if (!scale) scale = 1;
      for(i = 0; i < poly.length; i++) {
        for(j = 0; j < poly[i].length; j++) {
          poly[i][j].X *= scale;
          poly[i][j].Y *= scale;
        }
      }
      return poly;
    }

    // converts polygons to SVG path string
    function polys2path (poly, scale) {
      var path = "", i, j;
      if (!scale) scale = 1;
      for(i = 0; i < poly.length; i++) {
        for(j = 0; j < poly[i].length; j++){
          if (!j) path += "M";
          else path += "L";
          path += (poly[i][j].X / scale) + ", " + (poly[i][j].Y / scale);
        }
        path += "Z";
      }
      return path;
    }

    function reverse_copy(poly) {
        // Make reverse copy of polygons = convert polyline to a 'flat' polygon ...
      var k, klen = poly.length, len, j; 
      for (k = 0; k < klen; k++) {
        len = poly[k].length;
        poly[k].length = len * 2 - 2;
        for (j = 1; j <= len - 2; j++) {
          poly[k][len - 1 + j] = {
            X: poly[k][len - 1 - j].X,
            Y: poly[k][len - 1 - j].Y
          }
        }
      }
    }
        </script>
      </head>
      <body onload="draw()">

        <div id="svgcontainer"></div>
      </body>
    </html>

有没有一种简单的方法可以将 SVG 路径转换为 ​​Canvas。我需要这个,因为我需要在移动设备上展示这个例子,并且 Canvas 在移动设备上比 canvas 有更好的性能。

这段代码我需要转换成CANVAS:

 // Draw red offset polygon
      svg = '<svg style="margin-top:10px;margin-right:10px;margin-bottom:10px;background-color:#dddddd" width="800" height="600">';
      svg += '<path stroke="red" fill="red" stroke-width="2" stroke-opacity="0.6" fill-opacity="0.2" d="' + polys2path(offsetted_polygon, scale) + '"/>';

      //Draw blue polyline
      svg += '<path stroke="blue" stroke-width="1" d="' + polys2path(polygons, scale) + '"/>';
      svg += '</svg>';

如何将 SVG 路径转换为简单的 CANVAS 路径?

您可以使用 canvg 库将 svg 转换为 canvas。

您应该将所有必需的 js 文件包含到您的页面中,然后像这样使用它:

canvg(document.getElementById('canvasElement'), '<svg>...</svg>')

当然,呈现复杂折线的最快方法是将其转换为图像。

复杂折线的完全优化 canvas 版本将涉及 canvas 路径:

  1. 使用带有贝塞尔曲线的线条创建红色轮廓的闭合路径以进行连接。您可以使用 context.lineTocontext.quadraticCurveTo + context.bezierCurveTo 来定义路径。生成的路径通常称为样条曲线。

  2. 用红色描边路径

  3. 用粉红色填充路径。

  4. 画蓝线。

这并不难,但确实涉及一些三角学(主要是找到与折线向量相切的点)。

这是一个使用阴影来模仿复杂 SVG 多段线的替代方法:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;


var pts = [{x:22,y:59.45},{x:136,y:66},{x:170,y:99},{x:171,y:114},{x:183,y:125},{x:218,y:144},{x:218,y:165},{x:226,y:193},{x:254,y:195},{x:283,y:195},{x:292,y:202},{x:325,y:213},{x:341,y:134},{x:397,y:245},{x:417,y:548}];

mimicSvg(pts);

function mimicSvg(pts){

  // make caps & joins round
  ctx.lineCap='round';
  ctx.lineJoin='round';


  // draw the outside line with red shadow
  ctx.shadowColor='red';
  ctx.shadowBlur='2';
  ctx.lineWidth=25;
  // draw multiple times to darken shadow
  drawPolyline(pts);
  drawPolyline(pts);
  drawPolyline(pts);

  // stop shadowing
  ctx.shadowColor='transparent';

  // refill the outside line with pink
  ctx.strokeStyle='pink';
  drawPolyline(pts);

  // draw the inside line
  ctx.lineWidth=2;
  ctx.strokeStyle='blue';
  drawPolyline(pts);

}

function drawPolyline(pts){
  ctx.beginPath();
  ctx.moveTo(pts[0].x,pts[0].y);
  for(var i=1;i<pts.length;i++){
    ctx.lineTo(pts[i].x,pts[i].y);
  }
  ctx.stroke();
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=500 height=600></canvas>