嘿,我根据在画布上创建duval三角形的帖子创建了一个Duval五角大楼:how to create Duval Triangle in canvas。 我的最终结果应该是:
我目前的情况是,我可以创建五角大楼内的所有部分,但我没有找到在我的duval五角大楼的每个角落(点)周围放置气体标签的方法,任何建议或帮助是欢迎。
创建duval五边形流程是这样的:
1.创造外五角大楼。
2.创建循环中的所有细分。
3.创建五角大楼的传奇。
更新 我已经尝试根据@markE引导线再次构建分子标签。到目前为止没有那么好尝试过,我肯定做错了什么。 :(
2.3
function moleculeLabel(V,P,text){
var dx=V.x-P.x;
var dy=V.y-P.y;
var rAngle=Math.atan2(dy,dx);
var padding=15; // == how far outside the pentagon you want to go
var outsideX=P.x+(P.radius+padding)*Math.cos(rAngle);
var outsideY=P.y+(P.radius+padding)*Math.sin(rAngle);
ctx.textAlign='center';
ctx.textBaseline='middle';
ctx.fillStyle='black';
ctx.fillText(text,outsideX,outsideY);
}`
$(function() {
//offset :
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var points = [{
x: 397,
y: 149
}, {
x: 318,
y: 346
}, {
x: 112,
y: 347
}, {
x: 44,
y: 147
}, {
x: 221,
y: 27
}, {
x: 397,
y: 149
}];
var cx = 0;
var cy = 0;
for (var i = 0; i < points.lenght; i++) {
cx = cx + points[i].x;
cy = cy + points[i].y;
}
cx = cx / points.lenght;
cy = cy / points.lenght;
var centerPoint = {
x: cy,
y: cy
};
// Define all your segments here
var segments = [{
points: [{
x: 61,
y: 191
}, {
x: 112,
y: 347
}, {
x: 190,
y: 223
}, {
x: 214,
y: 211
}, {
x: 217,
y: 198
}, {
x: 61,
y: 192
}],
fill: 'rgb(172,236,222)',
label: {
text: 'T1',
cx: 130,
cy: 250,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 61,
y: 191
}, {
x: 217,
y: 198
}, {
x: 220,
y: 26
}, {
x: 44,
y: 149
}],
fill: 'deepskyblue',
label: {
text: 'S',
cx: 140,
cy: 150,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 220,
y: 26
}, {
x: 217,
y: 198
}, {
x: 239,
y: 135
}, {
x: 365,
y: 230
}, {
x: 397,
y: 149
}, {
x: 221,
y: 27
}],
fill: 'lightCyan',
label: {
text: 'D1',
cx: 270,
cy: 110,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 214,
y: 211
}, {
x: 239,
y: 135
}, {
x: 365,
y: 231
}, {
x: 320,
y: 336
}, ],
fill: 'navajoWhite',
label: {
text: 'D2',
cx: 270,
cy: 210,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 190,
y: 223
}, {
x: 214,
y: 211
}, {
x: 320,
y: 336
}, {
x: 318,
y: 346
}, {
x: 223,
y: 346
}],
fill: 'tan',
label: {
text: 'T3',
cx: 250,
cy: 310,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 112,
y: 347
}, {
x: 190,
y: 223
}, {
x: 223,
y: 346
}],
fill: 'peru',
label: {
text: 'T2',
cx: 175,
cy: 300,
withLine: false,
endX: null,
endY: null
},
}, {
points: [{
x: 210,
y: 105
}, {
x: 219,
y: 105
}, {
x: 219,
y: 68
}, {
x: 210,
y: 67
}],
fill: 'red',
label: {
text: 'PD',
cx: 170,
cy: 87,
withLine: true,
endX: 215,
endY: 88
},
}];
// label styles
var labelfontsize = 12;
var labelfontface = 'verdana';
var labelpadding = 3;
var legendTexts = ['PD = Partial Discharge', 'T1 = Thermal fault < 300 celcius', '...'];
// start drawing
/////////////////////
// draw pentagon
drawPentagon(points);
// draw colored segments inside pentagon
for (var i = 0; i < segments.length; i++) {
drawSegment(segments[i]);
}
moleculeLabel(points[0], centerPoint, 'CH4');
moleculeLabel(points[1], centerPoint, 'CH2');
moleculeLabel(points[2], centerPoint, 'H2');
// draw legend
drawLegend(legendTexts, 10, 10, 12.86);
// end drawing
/////////////////////
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 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 moleculeLabel(V, P, text) {
var dx = V.x - P.x;
var dy = V.y - P.y;
var rAngle = Math.atan2(dy, dx);
var padding = 15; // == how far outside the pentagon you want to go
var outsideX = P.x + (P.radius + padding) * Math.cos(rAngle);
var outsideY = P.y + (P.radius + padding) * Math.sin(rAngle);
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillStyle = 'black';
ctx.fillText(text, outsideX, outsideY);
}
/**
* draw basic pentagon.
**/
function drawPentagon(points) {
ctx.beginPath();
for (var i = 0; i < points.length; i++) {
ctx.lineTo(points[i].x, points[i].y);
}
ctx.strokeStyle = 'black';
ctx.lineWidth = 1;
ctx.stroke();
ctx.closePath();
}
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;
}
答案 0 :(得分:0)
最后的答案,非常感谢@markE。
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var points = [{x:397,y:149},{x:318,y:346},{x:112,y:347},{x:44,y:147},{x: 221,y:27},{x:397,y:149}];
// calc the polygon center mass
var cx,cy;
var totx=0;
var toty=0;
for(var i=0;i<points.length-1;i++){ // don't include the "closing" point in points[]
totx+=points[i].x;
toty+=points[i].y;
}
cx=totx/(points.length-1);
cy=toty/(points.length-1);
draw();
function draw(){
// draw the polygon
ctx.beginPath();
ctx.moveTo(points[0].x,points[0].y);
for(var i=1;i<points.length;i++){
ctx.lineTo(points[i].x,points[i].y);
}
ctx.stroke();
// draw the labels at their radial extension points
ctx.textAlign='center';
ctx.textBaseline='middle';
var padding=20;
for(var i=0;i<points.length-1;i++){
var p=points[i];
var dx=p.x-cx;
var dy=p.y-cy;
var dist=Math.sqrt(dx*dx+dy*dy);
var rAngle=Math.atan2(dy,dx);
var labelX=cx+(dist+padding)*Math.cos(rAngle);
var labelY=cy+(dist+padding)*Math.sin(rAngle);
ctx.fillText('label#'+i,labelX,labelY)
// demo only, for points[0] draw the
//centerpoint and the radial extension point
if(i==0){
ctx.beginPath();
ctx.moveTo(cx,cy);
ctx.lineTo(labelX,labelY);
ctx.moveTo(cx,cy);
ctx.arc(cx,cy,5,0,Math.PI*2);
ctx.moveTo(labelX,labelY);
ctx.arc(labelX,labelY,3,0,Math.PI*2);
ctx.strokeStyle='red';
ctx.stroke();
ctx.fillStyle='red';
ctx.fill();
ctx.strokeStyle='black';
ctx.fillStyle='black';
}
}
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<canvas id="canvas" width=500 height=500></canvas>