将 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 路径:
使用带有贝塞尔曲线的线条创建红色轮廓的闭合路径以进行连接。您可以使用 context.lineTo
和 context.quadraticCurveTo
+ context.bezierCurveTo
来定义路径。生成的路径通常称为样条曲线。
用红色描边路径
用粉红色填充路径。
画蓝线。
这并不难,但确实涉及一些三角学(主要是找到与折线向量相切的点)。
这是一个使用阴影来模仿复杂 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>
这里我有一些制作 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 路径:
使用带有贝塞尔曲线的线条创建红色轮廓的闭合路径以进行连接。您可以使用
context.lineTo
和context.quadraticCurveTo
+context.bezierCurveTo
来定义路径。生成的路径通常称为样条曲线。用红色描边路径
用粉红色填充路径。
画蓝线。
这并不难,但确实涉及一些三角学(主要是找到与折线向量相切的点)。
这是一个使用阴影来模仿复杂 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>