<template>
<div class="app-container">
<div class="d-flex j-center">
<!--用来和鼠标进行交互操作的canvas-->
<canvas
id="canvas"
width="1000px"
height="600px"
@mousedown="canvasDown"
@mousemove="canvasMove"
></canvas>
<!--存储已生成的点线,避免被清空-->
<canvas id="canvasSave" width="1000px" height="600px"></canvas>
<el-button
class="deleteCanvas"
id="deleteCanvas"
type="primary"
@click="deleteCanvasClick"
>清空选区</el-button
>
<!--canvas回显-->
<!-- <canvas class="shaped" id="quad"></canvas> -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
can: null,
ctx: null,
canSave: null,
ctxSave: null,
pointX: null,
pointY: null,
pointArr: [], //存放坐标的数组
oIndex: -1, //判断鼠标是否移动到起始点处,-1为否,1为是
//回显数据
pointColorArr: [
{
color: "#f7b5c1",
houseName: "601单元",
ponitArr: [
{
x: 2,
y: 133,
},
{
x: 2,
y: 401,
},
{
x: 166,
y: 401,
},
{
x: 167,
y: 134,
},
{
x: 2,
y: 133,
},
],
},
{
color: "#bcf7d9",
houseName: "602单元",
ponitArr: [
{
x: 442,
y: 403,
},
{
x: 440,
y: 347,
},
{
x: 581,
y: 347,
},
{
x: 584,
y: 568,
},
{
x: 5,
y: 566,
},
{
x: 3,
y: 401,
},
{
x: 442,
y: 403,
},
],
},
],
};
},
mounted() {
//初始化画布对象
this.can = document.getElementById("canvas");
this.ctx = this.can.getContext("2d");
this.canSave = document.getElementById("canvasSave");
this.ctxSave = this.canSave.getContext("2d");
this.ctx.strokeStyle = "rgba(102,168,255,1)"; //线条颜色
this.ctx.lineWidth = 4; //线条粗细
this.ctxSave.strokeStyle = "rgba(102,168,255,1)"; //线条颜色
this.ctxSave.lineWidth = 4; //线条粗细
this.init();
},
methods: {
//初始化回显
init() {
this.pointColorArr.map((item) => {
this.canvasFill(item.ponitArr, item.color, item.houseName);
});
},
/*点击画点*/
canvasDown(e) {
if (e.offsetX || e.layerX) {
this.pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
this.pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
var piX, piY;
if (this.oIndex > 0 && this.pointArr.length > 0) {
piX = this.pointArr[0].x;
piY = this.pointArr[0].y;
//画点
this.makearc(
this.ctx,
piX,
piY,
this.GetRandomNum(2, 2),
0,
180,
"rgba(102,168,255,1)"
);
this.pointArr.push({ x: piX, y: piY });
this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
this.saveCanvas(); //生成画布
} else {
piX = this.pointX;
piY = this.pointY;
this.makearc(
this.ctx,
piX,
piY,
this.GetRandomNum(2, 2),
0,
180,
"rgba(102,168,255,1)"
);
this.pointArr.push({ x: piX, y: piY });
this.canvasSave(this.pointArr); //保存点线同步到另一个canvas
}
}
},
// 鼠标移动事件
canvasMove(e) {
if (e.offsetX || e.layerX) {
this.pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
this.pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
var piX, piY;
/*清空画布*/
this.ctx.clearRect(0, 0, this.can.width, this.can.height);
/*鼠标下跟随的圆点*/
this.makearc(
this.ctx,
this.pointX,
this.pointY,
this.GetRandomNum(4, 4),
0,
180,
"rgba(102,168,255,1)"
);
if (this.pointArr.length > 0) {
if (
this.pointX > this.pointArr[0].x - 15 &&
this.pointX < this.pointArr[0].x + 15 &&
this.pointY > this.pointArr[0].y - 15 &&
this.pointY < this.pointArr[0].y + 15
) {
if (this.pointArr.length > 1) {
piX = this.pointArr[0].x;
piY = this.pointArr[0].y;
this.ctx.clearRect(0, 0, this.can.width, this.can.height);
this.makearc(
this.ctx,
piX,
piY,
this.GetRandomNum(4, 4),
0,
180,
"rgba(102,168,255,1)"
);
this.oIndex = 1;
}
} else {
piX = this.pointX;
piY = this.pointY;
this.oIndex = -1;
}
/*开始绘制*/
this.ctx.beginPath();
this.ctx.moveTo(this.pointArr[0].x, this.pointArr[0].y);
if (this.pointArr.length > 1) {
for (var i = 1; i < this.pointArr.length; i++) {
this.ctx.lineTo(this.pointArr[i].x, this.pointArr[i].y);
}
}
this.ctx.lineTo(piX, piY);
this.ctx.fillStyle = "rgba(161,195,255,1)"; //填充颜色
this.ctx.fill(); //填充
this.ctx.stroke(); //绘制
}
}
},
// 存储已生成的点线
canvasSave(pointArr) {
this.ctxSave.clearRect(0, 0, this.ctxSave.width, this.ctxSave.height);
this.ctxSave.beginPath();
if (pointArr.length > 1) {
this.ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
for (var i = 1; i < pointArr.length; i++) {
this.ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
this.ctxSave.fillStyle = "rgba(161,195,255,0.2)"; //填充颜色
//this.ctxSave.fill();
this.ctxSave.stroke(); //绘制
}
this.ctxSave.closePath();
}
console.log("存储已生成的点线", pointArr);
//判断最后一个点重合则结束绘制
if (pointArr.length > 1) {
let { 0: a, [pointArr.length - 1]: b } = pointArr;
if (a.x == b.x && b.y == b.y) {
console.log("结束绘制");
}
}
},
//回显canvas区域
canvasFill(pointArr, color, houseName) {
this.ctxSave.clearRect(0, 0, this.ctxSave.width, this.ctxSave.height);
this.ctxSave.beginPath();
if (pointArr.length > 1) {
this.ctxSave.moveTo(pointArr[0].x, pointArr[0].y);
for (var i = 1; i < pointArr.length; i++) {
this.ctxSave.lineTo(pointArr[i].x, pointArr[i].y);
}
this.ctxSave.fillStyle = `${color}B3`; //填充颜色 ${color}6B ${color}
this.ctxSave.fill();
this.ctxSave.stroke(); //绘制
this.canvasText(houseName, pointArr[0]);
}
},
//绘制文字
canvasText(text, point) {
this.ctxSave.font = "30px Consolas"; //字体样式的属性
this.ctxSave.textAlign = "center"; //设置文本对齐方式
this.ctxSave.textBaseline = "middle"; //文本基线
let textWidth = this.ctxSave.measureText(text).width;
var canvasWidth = this.can.width;
console.log("canvasWidth", canvasWidth);
this.ctxSave.fillStyle = "red"; //字体颜色
this.ctxSave.fillText(text, point.x + 70, point.y + 100); //绘制文字
this.ctxSave.arc(point.x, point.y, 3, 0, Math.PI * 2); //基准点
},
/*生成画布 结束绘画*/
saveCanvas() {
this.ctx.clearRect(0, 0, this.can.width, this.can.height);
this.ctxSave.closePath(); //结束路径状态,结束当前路径,如果是一个未封闭的图形,会自动将首尾相连封闭起来
this.ctxSave.fill(); //填充
this.ctxSave.stroke(); //绘制
this.pointArr = [];
},
//清空选区
deleteCanvasClick() {
this.ctx.clearRect(0, 0, this.can.width, this.can.height);
this.ctxSave.clearRect(0, 0, this.canSave.width, this.canSave.height);
this.pointArr = [];
},
/*验证canvas画布是否为空函数*/
isCanvasBlank(canvas) {
var blank = document.createElement("canvas"); //创建一个空canvas对象
blank.width = canvas.width;
blank.height = canvas.height;
return canvas.toDataURL() == blank.toDataURL(); //为空 返回true
},
/*canvas生成圆点*/
GetRandomNum(Min, Max) {
var Range = Max - Min;
var Rand = Math.random();
return Min + Math.round(Rand * Range);
},
makearc(ctx, x, y, r, s, e, color) {
ctx.clearRect(0, 0, 199, 202); //清空画布
ctx.beginPath();
ctx.fillStyle = color;
ctx.arc(x, y, r, s, e);
ctx.fill();
},
},
};
</script>
<style lang="scss" scoped>
canvas {
border: 1px solid #333;
display: block;
}
.deleteCanvas {
width: 100px;
margin-left: 200px;
margin-top: 650px;
}
#canvas {
position: absolute;
left: 200px;
top: 0;
z-index: 1;
cursor: crosshair;
}
#canvasSave {
position: absolute;
left: 200px;
top: 0;
}
#canvasSave {
background-image: url("../../../assets/images/office.png");
background-repeat: no-repeat;
background-size: 600px;
}
</style>
vue canvas 绘制多个多边形,并且可以根据坐标数据回显
最新推荐文章于 2023-10-24 13:42:52 发布