1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
| <!DOCTYPE html> <html>
<head> <title>绘制复杂路径</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content="图形系统开发实战:基础篇 示例"> <meta name="author" content="hjq"> <meta name="keywords" content="canvas,ladder,javascript,图形"> <script src="./js/helper.js"></script> <script src="./js/path.js"></script> </head>
<body style="overflow: hidden; margin:10px;"> <canvas id="canvas" width="600" height="520" style="border:solid 1px #CCCCCC;"></canvas> </body> <script> let canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); drawGrid('lightgray', 10, 10);
let datas = [ "m782.98 577.54a387.3 397.46 0 1 0 -774.61 0 387.3 397.46 0 1 0 774.61 0z", "m378.74 182.34s -109.95 45.977 -112.21 398.28 c -2.2584 352.3 123.5 394.4 123.5 394.4", "m378.74 182.34s338.75 45.166 336.49 397.46 c -2.2583 352.3 -325.2 395.21 -325.2 395.21", "m378.74 182.34s121.21 47.46 118.95 399.76 c -2.2584 352.3 -107.66 392.91 -107.66 392.91", "m378.74 182.34s -307.84 40.684 -310.1 392.98 c -2.2583 352.3 321.39 399.69 321.39 399.69", "m378.74 182.34s225.83 40.65 223.57 392.95 c -2.2582 352.3 -212.28 399.72 -212.28 399.72", "m378.74 182.34s -227.72 42.236 -229.98 394.54 c -2.2584 352.3 241.27 398.14 241.27 398.14", "m378.74 182.34s6.775 33.875 4.5166 386.17 c -2.2582 352.3 6.7749 406.5 6.7749 406.5", "m240.98 213.95s9.0333 51.942 140.02 51.942c130.98 0 169.37 -47.425 169.37 -47.425", "m113.88 306.54s6.4347 79.041 265.11 79.041 307.51 -74.525 302.99 -72.266", "m48.895 399.13s29.877 101.62 332.11 101.62 363.72 -92.591 363.72 -92.591", "m13.009 523.34s49.446 83.558 373.46 83.558 391.88 -79.041 391.88 -79.041", "m13.012 615.93s47.121 94.85 370.17 94.85 392.9 -90.333 392.9 -90.333", "m35.368 715.3s45.75 88.075 348.92 88.075 367.19 -83.558 367.19 -83.558", "m84.569 812.41s38.426 76.783 300.89 76.783 319.07 -72.266 319.07 -72.266", "m156.1 884.67s31.99 72.267 233.89 72.267 243.01 -67.75 243.01 -67.75"]; ctx.scale(0.6, 0.6); ctx.translate(100, -140);
ctx.strokeStyle = "black"; ctx.lineWidth = 3;
for (let i = 0; i < datas.length; i++) { let pathData = pathParse(datas[i]); let lastPoint = [0, 0]; let c_lastControlPoint = [0, 0]; let q_lastControlPoint = [0, 0];
ctx.beginPath();
for (let j = 0; j < pathData.length; j++) { if (pathData[j][0] == "M") { ctx.moveTo(pathData[j][1], pathData[j][2]); lastPoint = [pathData[j][1], pathData[j][2]]; } else if (pathData[j][0] == "L") { ctx.lineTo(pathData[j][1], pathData[j][2]); lastPoint = [pathData[j][1], pathData[j][2]]; } else if (pathData[j][0] == "H"){ ctx.lineTo(pathData[j][1], lastPoint[1]); lastPoint = [pathData[j][1], lastPoint[1]]; } else if (pathData[j][0] == "V"){ ctx.lineTo(lastPoint[0], pathData[j][1]); lastPoint = [lastPoint[0], pathData[j][1]]; } else if (pathData[j][0] == "A") { let arcArray = fromArcToBeziers(lastPoint[0], lastPoint[1], pathData[j]); for(let idx = 0; idx<arcArray.length; idx ++) { ctx.bezierCurveTo(arcArray[idx][1], arcArray[idx][2], arcArray[idx][3], arcArray[idx][4], arcArray[idx][5], arcArray[idx][6]); lastPoint = [arcArray[idx][5], arcArray[idx][6]]; } } else if (pathData[j][0] == "S") { if (c_lastControlPoint[0] == 0 && c_lastControlPoint[1] == 0) { c_lastControlPoint = lastPoint.slice(); } else { c_lastControlPoint = getSymmetricPointRelative(c_lastControlPoint, lastPoint); } ctx.bezierCurveTo(c_lastControlPoint[0], c_lastControlPoint[1], pathData[j][1], pathData[j][2], pathData[j][3], pathData[j][4]); c_lastControlPoint = [pathData[j][1], pathData[j][2]] lastPoint = [pathData[j][3], pathData[j][4]]; } else if (pathData[j][0] == "C") { ctx.bezierCurveTo(pathData[j][1], pathData[j][2], pathData[j][3], pathData[j][4], pathData[j][5], pathData[j][6]); c_lastControlPoint = [pathData[j][3], pathData[j][4]]; lastPoint = [pathData[j][5], pathData[j][6]]; } else if (pathData[j][0] == "Q") { ctx.quadraticCurveTo(pathData[j][1], pathData[j][2], pathData[j][3], pathData[j][4]); q_lastControlPoint = [pathData[j][1], pathData[j][2]]; lastPoint = [pathData[j][3], pathData[j][4]]; } else if (pathData[j][0] == "T") { if (q_lastControlPoint[0] == 0 && q_lastControlPoint[1] == 0) { q_lastControlPoint = lastPoint.slice(); } else { q_lastControlPoint = getSymmetricPointRelative(q_lastControlPoint, lastPoint); } lastPoint = [pathData[j][1], pathData[j][2]]; } else if (pathData[j][0] == "Z" || pathData[j][0] == "z") { ctx.closePath(); } }
ctx.stroke(); } </script>
</html>
|