0

Here I have some code that make svg path:

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> 

Is there a simple way to tranform SVG path to Canvas. I need this becouse I need to show this example on mobile devices and Canvas have a better performance than canvas on mobile devices.

This code I need to transform to 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>'; 

How I can transform SVG path to simple CANVAS path?

0

2 Answers 2

2

You can use canvg library to convert svg to canvas.

You should include all its necessary js files to your page and then use it something like this:

canvg(document.getElementById('canvasElement'), '<svg>...</svg>') 
Sign up to request clarification or add additional context in comments.

2 Comments

Also I dont want to use CANVG becouse its 99% slower than regular generated canvas... I use canvas becouse I need speed and mobile optimized code
I though won't convert your svg to canvas on the fly all the time, you need to do it just once and then use canvas way to do other drawings, e.g.here you can convert your svg online (it uses same way that Imentioned)
1

Of course, the fastest way to present your complex polyline is to convert it into an image.

A fully optimized canvas version of your complex polyline would involve a canvas path:

  1. Create a closed path of your red outline using lines with Bezier curves for joins. You can use context.lineTo and context.quadraticCurveTo + context.bezierCurveTo to define the path. The resulting path is commonly called a spline.

  2. Stroke the path with red.

  3. Fill the path with pink.

  4. Draw the blue line.

This is not hard to do but does involve some trigonometry (mainly finding points tangent to the vectors of your polyline).

Here's an alternative that uses shadowing to mimic your complex SVG polyline:

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>

2 Comments

so this canvas is faster than my example with SVG ? Thanks for answer but I dont need shadow I really need to calculate points for offset polygon becouse I need it later to calculate m2.
Fair enough...then you're left with deconstructing the outside path with lines and curves (a spline). Good luck with your project! :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.