其实原理很简单,只不过要我们回归一下下学生时代学习的三角函数
原理后面再补充,我先上代码
line.js --------- 这个文件是用来封装canvas对象的
/*
* x1,y1 第一个点的坐标
* x2,y2 第二个点的坐标
* type 箭头的方向
* color 整体颜色 (如果需要箭头和直线颜色分离的话,再加一个参数)
* arrows 是否需要箭头 true代表需要
*/
class Line {
constructor(x1, y1, x2, y2, type, color, arrows) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.type = type;
this.color = color;
this.arrows = arrows;
}
draw (ctx) {
// 设置箭头样式
ctx.strokeStyle = this.color;
ctx.fillStyle = this.color;
ctx.lineWidth = 1;
// 画线
ctx.beginPath();
ctx.moveTo(this.x1, this.y1);
ctx.lineTo(this.x2, this.y2);
ctx.stroke();
if (this.arrows) {
this.drawHasArrow(ctx);
}
}
drawHasArrow (ctx) {
let d = 6;
let angle = 15;
if (this.type == 0) {
// 画向上的箭头
this.drawArrowhead(ctx, this.x2, this.y2, this.x2 - Math.tan(angle) * d, this.y2 + d, this.x2 + Math.tan(angle) * d, this.y2 + d)
} else if (this.type == 1) {
// 画向下的箭头
this.drawArrowhead(ctx, this.x2, this.y2, this.x1 - Math.tan(angle) * d, this.y2 - d, this.x1 + Math.tan(angle) * d, this.y2 - d)
} else {
// 画向右的箭头
this.drawArrowhead(ctx, this.x2, this.y2, this.x2 - d, this.y1 - Math.tan(angle) * d, this.x2 - d, Math.tan(angle) * d + this.y1)
}
}
drawArrowhead (ctx, x, y, x3, y3, x4, y4) {
ctx.save();
ctx.beginPath();
ctx.moveTo(x, y);
ctx.lineTo(x3, y3);
ctx.lineTo(x4, y4);
ctx.closePath();
ctx.restore();
ctx.fill();
}
}
export default Line;
我的使用方法如下(例子使用的框架是vue2)
我是用的是批量画线的方法,当然你也可以画单个线,如果画单个线,只需要把drawLine的for循环里面的代码提出来,改下参数就行。
<script>
import Line from "./Line.js";
export default {
data () {
return {
c: null,
ctx: null,
// 初始坐标
initX: 100,
initY: 22,
lineInfo: {}
}
},
methods: {
canvasInit () {
this.c = this.$refs.myRelativeCanvas;
// 这里是设置canvas画布的宽高,我是需要做成自适应宽高的,所以我依赖"ete-relative-box"这个自适应dom
this.c.width = document.getElementsByClassName("ete-relative-box")[0].clientWidth * 0.95
this.c.height = document.getElementsByClassName("ete-relative-box")[0].clientHeight * 0.95
this.ctx = this.c.getContext("2d");
},
drawLine () {
this.initLineInfo();
for (let key in this.lineInfo) {
let line = new Line(
this.lineInfo[key].x1,
this.lineInfo[key].y1,
this.lineInfo[key].x2,
this.lineInfo[key].y2,
this.lineInfo[key].type,
this.lineInfo[key].color,
this.lineInfo[key].arrows
);
line.draw(this.ctx);
}
},
// 这个函数可以用来批量画
initLineInfo () {
this.lineInfo = {
solved_research: {
x1: this.initX + 260,
y1: this.initY + 45,
x2: this.initX + 260,
y2: this.initY + 194,
type: 1,
arrows: true,
color: "#b7b7b7de"
},
research_normal: {
x1: this.initX + 320,
y1: this.initY + 210,
x2: this.initX + 490,
y2: this.initY + 210,
type: 2,
arrows: true,
color: "#706368"
},
doa_air_closed: {
x1: this.initX + 1290,
y1: this.initY + 301,
x2: this.initX + 1290,
y2: this.initY + 225,
type: 0,
arrows: true,
color: "#b7b7b7de"
},
research_air_air_up: {
x1: this.initX + 430,
y1: this.initY + 210,
x2: this.initX + 430,
y2: this.initY + 119,
type: 1,
arrows: false,
color: "#4cadab"
}
}
}
},
created () {
this.$nextTick(function () {
this.canvasInit();
this.drawLine();
})
}
}
</script>