簡體   English   中英

將代碼從畫布轉換為 svg

[英]Convert code from canvas to svg

我在畫布中有一個代碼,可以幫助我制作氣體三角形(duval 三角形)。 我需要將代碼從畫布轉換為 svg。 我從畫布移動到 svg 的原因之一是因為我無法在畫布中添加事件處理程序(其作用類似於位圖),但在 svg 中我可以做到。

1.有可能嗎?

2.我可以在畫布上做同樣的事情也在svg嗎?

3.我應該使用庫來幫助我編寫svg,對於特定的svg庫有什么建議嗎?

我的代碼基於以下帖子: 如何在畫布中創建杜瓦爾三角形

 $(function() { var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); // https://www.researchgate.net/publication/4345236_A_Software_Implementation_of_the_Duval_Triangle_Method var v0 = { x: 58, y: 845 }; var v1 = { x: 984, y: 845 }; var v2 = { x: 521, y: 41 }; var triangle = [v0, v1, v2]; // Define all your segments here var segments = [{ points: [{ x: 58, y: 845 }, { x: 272, y: 845 }, { x: 567, y: 333 }, { x: 461, y: 150 }], fill: 'rgb(172,236,222)', label: { text: 'D1', cx: 300, cy: 645, withLine: false, endX: null, endY: null }, }, { points: [{ x: 272, y: 845 }, { x: 567, y: 333 }, { x: 646, y: 468 }, { x: 572, y: 597 }, { x: 716, y: 845 }], fill: 'deepskyblue', label: { text: 'D2', cx: 490, cy: 645, withLine: false, endX: null, endY: null }, }, { points: [{ x: 716, y: 845 }, { x: 845, y: 845 }, { x: 683, y: 565 }, { x: 734, y: 476 }, { x: 503, y: 76 }, { x: 461, y: 150 }, { x: 646, y: 468 }, { x: 572, y: 595 }], fill: 'lightCyan', label: { text: 'DT', cx: 656, cy: 645, withLine: false, endX: 366, endY: 120 }, }, { //here - I am in hell.-s5 points: [{ x: 530, y: 59 }, { x: 512, y: 59 }, { x: 521, y: 41 }], fill: 'black', label: { text: 'PD', cx: 600, cy: 52, withLine: true, endX: 520, endY: 70 }, }, { points: [{ x: 595, y: 235 }, { x: 614, y: 203 }, { x: 530, y: 59 }, { x: 512, y: 59 }, { x: 503, y: 76 }], fill: 'navajoWhite', label: { text: 'T1', cx: 670, cy: 140, withLine: true, endX: 574, endY: 105 }, }, { points: [{ x: 753, y: 446 }, { x: 735, y: 476 }, { x: 595, y: 235 }, { x: 614, y: 203 }], fill: 'tan', label: { text: 'T2', cx: 800, cy: 290, withLine: true, endX: 662, endY: 120 }, }, { points: [{ x: 845, y: 845 }, { x: 683, y: 565 }, { x: 753, y: 446 }, { x: 984, y: 845 }], fill: 'peru', label: { text: 'T3', cx: 800, cy: 645, withLine: false, endX: null, endY: null }, }, ]; // label styles var labelfontsize = 12; var labelfontface = 'verdana'; var labelpadding = 3; // pre-create a canvas-image of the arrowhead var arrowheadLength = 10; var arrowheadWidth = 8; var arrowhead = document.createElement('canvas'); premakeArrowhead(); var legendTexts = ['PD = Partial Discharge', 'DT = Discharges and Thermal', 'T1 = Thermal fault T < 300 ℃', 'T2 = Thermal fault 300 ℃ < T < 700 ℃', 'T3 = Thermal fault T > 700 ℃', 'D1 = Discharges of low energy', 'D2 = Discharges of high energy' ]; // start drawing ///////////////////// // draw colored segments inside triangle for (var i = 0; i < segments.length; i++) { drawSegment(segments[i]); } // draw ticklines ticklines(v0, v1, 9, Math.PI * 1.2, 20); ticklines(v1, v2, 9, Math.PI * 3 / 4, 20); ticklines(v2, v0, 9, Math.PI * 2, 20); // molecules moleculeLabel(v0, v1, 100, Math.PI / 2, '% CH4'); moleculeLabel(v1, v2, 100, 0, '% C2H4'); moleculeLabel(v2, v0, 100, Math.PI, '% C2H2'); // draw outer triangle drawTriangle(triangle); // draw legend drawLegend(legendTexts, 10, 10, 12.86); drawCircle(canvas.width / 3, canvas.height / 2, 2.5, 'red'); // end drawing ///////////////////// function drawCircle(point1, point2, radius, color) { ctx.beginPath(); ctx.arc(point1, point2, radius, 0, 2 * Math.PI, false); ctx.fillStyle = color; ctx.fill(); } function drawSegment(s) { // draw and fill the segment path ctx.beginPath(); ctx.moveTo(s.points[0].x, s.points[0].y); for (var i = 1; i < s.points.length; i++) { ctx.lineTo(s.points[i].x, s.points[i].y); } ctx.closePath(); ctx.fillStyle = s.fill; ctx.fill(); ctx.lineWidth = 2; ctx.strokeStyle = 'black'; ctx.stroke(); // draw segment's box label if (s.label.withLine) { lineBoxedLabel(s, labelfontsize, labelfontface, labelpadding); } else { boxedLabel(s, labelfontsize, labelfontface, labelpadding); } } function moleculeLabel(start, end, offsetLength, angle, text) { ctx.textAlign = 'center'; ctx.textBaseline = 'middle' ctx.font = '14px verdana'; var dx = end.x - start.x; var dy = end.y - start.y; var x0 = parseInt(start.x + dx * 0.50); var y0 = parseInt(start.y + dy * 0.50); var x1 = parseInt(x0 + offsetLength * Math.cos(angle)); var y1 = parseInt(y0 + offsetLength * Math.sin(angle)); ctx.fillStyle = 'black'; ctx.fillText(text, x1, y1); // arrow var x0 = parseInt(start.x + dx * 0.35); var y0 = parseInt(start.y + dy * 0.35); var x1 = parseInt(x0 + 50 * Math.cos(angle)); var y1 = parseInt(y0 + 50 * Math.sin(angle)); var x2 = parseInt(start.x + dx * 0.65); var y2 = parseInt(start.y + dy * 0.65); var x3 = parseInt(x2 + 50 * Math.cos(angle)); var y3 = parseInt(y2 + 50 * Math.sin(angle)); ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x3, y3); ctx.strokeStyle = 'black'; ctx.lineWidth = 1; ctx.stroke(); var angle = Math.atan2(dy, dx); ctx.save(); // save ctx.translate(x3, y3); ctx.rotate(angle); ctx.drawImage(arrowhead, -arrowheadLength, -arrowheadWidth / 2); ctx.restore() } function boxedLabel(s, fontsize, fontface, padding) { var centerX = s.label.cx; var centerY = s.label.cy; var text = s.label.text; ctx.textAlign = 'center'; ctx.textBaseline = 'middle' ctx.font = fontsize + 'px ' + fontface var textwidth = ctx.measureText(text).width; var textheight = fontsize * 1.286; var leftX = centerX - textwidth / 2 - padding; var topY = centerY - textheight / 2 - padding; ctx.fillStyle = 'white'; ctx.fillRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2); ctx.lineWidth = 1; ctx.strokeRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2); ctx.fillStyle = 'black'; ctx.fillText(text, centerX, centerY); } function lineBoxedLabel(s, fontsize, fontface, padding) { var centerX = s.label.cx; var centerY = s.label.cy; var text = s.label.text; var lineToX = s.label.endX; var lineToY = s.label.endY; ctx.textAlign = 'center'; ctx.textBaseline = 'middle' ctx.font = fontsize + 'px ' + fontface var textwidth = ctx.measureText(text).width; var textheight = fontsize * 1.286; var leftX = centerX - textwidth / 2 - padding; var topY = centerY - textheight / 2 - padding; // the line ctx.beginPath(); ctx.moveTo(leftX, topY + textheight / 2); ctx.lineTo(lineToX, topY + textheight / 2); ctx.strokeStyle = 'black'; ctx.lineWidth = 1; ctx.stroke(); // the boxed text ctx.fillStyle = 'white'; ctx.fillRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2); ctx.strokeRect(leftX, topY, textwidth + padding * 2, textheight + padding * 2); ctx.fillStyle = 'black'; ctx.fillText(text, centerX, centerY); } function ticklines(start, end, count, angle, length) { var dx = end.x - start.x; var dy = end.y - start.y; ctx.lineWidth = 1; for (var i = 1; i < count; i++) { var x0 = parseInt(start.x + dx * i / count); var y0 = parseInt(start.y + dy * i / count); var x1 = parseInt(x0 + length * Math.cos(angle)); var y1 = parseInt(y0 + length * Math.sin(angle)); ctx.beginPath(); ctx.moveTo(x0, y0); ctx.lineTo(x1, y1); ctx.stroke(); if (i == 2 || i == 4 || i == 6 || i == 8) { var labelOffset = length * 3 / 4; var x1 = parseInt(x0 - labelOffset * Math.cos(angle)); var y1 = parseInt(y0 - labelOffset * Math.sin(angle)); ctx.fillStyle = 'black'; ctx.fillText(parseInt(i * 10), x1, y1); } } } function premakeArrowhead() { var actx = arrowhead.getContext('2d'); arrowhead.width = arrowheadLength; arrowhead.height = arrowheadWidth; actx.beginPath(); actx.moveTo(0, 0); actx.lineTo(arrowheadLength, arrowheadWidth / 2); actx.lineTo(0, arrowheadWidth); actx.closePath(); actx.fillStyle = 'black'; actx.fill(); } function drawTriangle(t) { ctx.beginPath(); ctx.moveTo(t[0].x, t[0].y); ctx.lineTo(t[1].x, t[1].y); ctx.lineTo(t[2].x, t[2].y); ctx.closePath(); ctx.strokeStyle = 'black'; ctx.lineWidth = 2; ctx.stroke(); } function drawLegend(texts, x, y, lineheight) { ctx.textAlign = 'left'; ctx.textBaseline = 'top'; ctx.fillStyle = 'black'; ctx.font = '12px arial'; for (var i = 0; i < texts.length; i++) { ctx.fillText(texts[i], x, y + i * lineheight); } } })
 body { background-color: ivory; padding: 10px; } #canvas { border: 1px solid red; margin: 0 auto; }
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <canvas id="canvas" width=1024 height=1020></canvas>

嘗試使用 fabric JS 將畫布轉換為 svg。 提琴手

HTML

<canvas id="canvas" width=1024 height=1020></canvas>
<button id="canvas2svg">Canvas 2 SVG</button>

JS

var canvas = new fabric.Canvas('canvas', { isDrawingMode: true });
  //var canvas = document.getElementById("canvas");
  var ctx = canvas.getContext("2d");
$("#canvas2svg").click(function(){
    canvas.isDrawingMode = false;
    alert(canvas.toSVG());
});

提琴手

另請參閱此示例小提琴

  1. 對的,這是可能的。

  2. 你可以在 svg 上比在畫布上做更多的事情。

  3. 你可以試試SVG.JS庫。 它重量輕且易於使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM