话不多说直接上代码
兼容触摸和pc
放组件中可以直接使用。这里注意外框要用百分比高度和宽度包裹上
<template>
<div class="selectquyu">
<canvas
:id="canvasid"
class="huabu"
:width="width"
:height="height"
></canvas>
</div>
</template>
<script>
export default {
data() {
return {
canvasid: "alldian",
width: "",
height: "",
selectColor: "#fff",
color: "#28B1D9",
areaColor: "rgba(40, 177, 217, 0.2)",
dianyi1: {
x: 70,
y: 100,
selectColor: "",
},
dianyi2: {
x: 140,
y: 25,
selectColor: "",
},
dianyi3: {
x: 70,
y: 150,
selectColor: "",
},
dianyi4: {
x: 140,
y: 150,
selectColor: "",
},
};
},
mounted() {
this.dowa();
},
methods: {
dowa() {
this.width = document.querySelector(".selectquyu").offsetWidth;
this.height = document.querySelector(".selectquyu").offsetHeight;
setTimeout(() => {
var canelem = document.getElementById(this.canvasid);
var cxt = canelem.getContext("2d");
this.initCanvas(cxt, this.width, this.height);
let { dianyi1, dianyi2, dianyi3, dianyi4 } = this;
this.isontouchend()?//判断是否支持触屏
this.touchesEvent(cxt, canelem, [dianyi1,dianyi2,dianyi3,dianyi4]):
this.mouseEvent(cxt, canelem, [dianyi1, dianyi2, dianyi3, dianyi4]);
}, 0);
},
isontouchend() {//判断是否支持触屏
return "ontouchend" in document ? true : false;
},
mouseEvent(cxt, element, dianyi) {
let xuznzhong = "";
element.onmousedown = (e) => {
console.log("1111", e);
var layerX = e.layerX; //计算出触摸距离当前画布的距离好进行移动
var layerY = e.layerY;
for (var i = 0; i < dianyi.length; i++) {
//进行循环查看哪个点是当前点击的点
xuznzhong = this.isBox(dianyi[i], layerX, layerY);
if (xuznzhong) {
xuznzhong.selectColor = this.selectColor;
break;
}
}
if (xuznzhong) {
element.onmousemove = (e) => {
xuznzhong.x = e.layerX;
xuznzhong.y = e.layerY;
this.initCanvas(cxt, this.width, this.height);
};
}
};
element.onmouseup = (e) => {
if (xuznzhong) {
xuznzhong.selectColor = "";
xuznzhong = null;
}
element.onmousemove = null;
this.initCanvas(cxt, this.width, this.height);
};
},
touchesEvent(cxt, element, dianyi) {
//触屏事件
var pingmuTop = element.getBoundingClientRect().top; //画布距离屏幕上面的距离 这里要计算出触摸距离当前画布的距离好进行移动
var pingmuLeft = element.getBoundingClientRect().left; //画布距离屏幕左面的距离
let xuznzhong = "";
element.ontouchstart = (e) => {
var layerX = e.touches[0].pageX - pingmuLeft; //计算出触摸距离当前画布的距离好进行移动
var layerY = e.touches[0].pageY - pingmuTop;
for (var i = 0; i < dianyi.length; i++) {
//进行循环查看哪个点是当前点击的点
xuznzhong = this.isBox(dianyi[i], layerX, layerY);
if (xuznzhong) {
xuznzhong.selectColor = this.selectColor;
break;
}
}
if (xuznzhong) {
element.ontouchmove = (e) => {
xuznzhong.x = e.touches[0].pageX - pingmuLeft;
xuznzhong.y = e.touches[0].pageY - pingmuTop;
this.initCanvas(cxt, this.width, this.height);
};
}
};
element.ontouchend = (e) => {
if (xuznzhong) {
xuznzhong.selectColor = "";
xuznzhong = null;
}
element.ontouchmove = null;
this.initCanvas(cxt, this.width, this.height);
};
},
initCanvas(cxt, width, height) {
//初始化画布
let { dianyi1, dianyi2, dianyi3, dianyi4 } = this;
cxt.clearRect(0, 0, width, height);
this.linedow(dianyi1, dianyi2, dianyi3, dianyi4, cxt);
this.dianyidow(dianyi1.x, dianyi1.y, cxt, dianyi1.selectColor);
this.dianyidow(dianyi2.x, dianyi2.y, cxt, dianyi2.selectColor);
this.dianyidow(dianyi3.x, dianyi3.y, cxt, dianyi3.selectColor);
this.dianyidow(dianyi4.x, dianyi4.y, cxt, dianyi4.selectColor);
},
dianyidow(x, y, cxt, selectColor) {
//画实心圆
cxt.fillStyle = selectColor || this.color;
cxt.beginPath();
cxt.arc(x, y, 18, 0, Math.PI * 2, true);
cxt.closePath();
cxt.fill();
cxt.beginPath();
cxt.arc(x, y, 18, 0, Math.PI * 2, true);
cxt.lineWidth = 4;
cxt.strokeStyle = this.color;
cxt.stroke(); //画空心圆
cxt.closePath();
},
linedow(dianyi1, dianyi2, dianyi3, dianyi4, cxt) {
let { color, areaColor } = this;
//画线
cxt.beginPath();
cxt.moveTo(dianyi1.x, dianyi1.y);
cxt.lineTo(dianyi2.x, dianyi2.y);
cxt.lineTo(dianyi4.x, dianyi4.y);
cxt.lineTo(dianyi3.x, dianyi3.y);
cxt.lineWidth = 2;
cxt.strokeStyle = color;
cxt.closePath();
cxt.fillStyle = areaColor;
cxt.fill();
cxt.stroke();
},
isBox(data, x, y, range = 22) {
//判断是否选中 选中返回当前点的坐标
if (
data.x - range < x &&
data.x + range > x &&
data.y - range < y &&
data.y + range > y
) {
return data;
} else {
return null;
}
},
},
};
</script>
<style lang="scss" scoped>
.selectquyu {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
z-index: 100;
.kuang {
position: relative;
width: 100px;
height: 100px;
border: 1px solid #27b2d9;
background-color: rgba($color: #28b1d9, $alpha: 0.2);
.dian {
position: absolute;
width: 18px;
height: 18px;
border: 4px solid #01deff;
// background-color: #28B1D9;
background-color: #fff;
border-radius: 50%;
}
.dian:nth-child(1) {
left: -10px;
top: -10px;
}
.dian:nth-child(2) {
left: -10px;
bottom: -10px;
}
.dian:nth-child(3) {
right: -10px;
top: -10px;
}
.dian:nth-child(4) {
right: -10px;
bottom: -10px;
}
}
}
</style>