将SVG路径转换为canvas html5

时间:2015-01-14 18:06:26

标签: javascript html5 canvas svg

这里我有一些制作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:

 // 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路径?

2 个答案:

答案 0 :(得分:2)

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

您应该将所有必要的js文件包含在您的页面中,然后使用它:

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

答案 1 :(得分:1)

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

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

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

  2. 用红色描绘路径。

  3. 用粉红色填充路径。

  4. 绘制蓝线。

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

    这是使用阴影来模拟复杂SVG折线的替代方法:

    enter image description here

    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>