核心步骤:鼠标每次拾取点位后,将点位保存到点位数组中,调用绘制方法。
绘制方法逻辑如下:
1、每次更新前清空画布
2、遍历点位数组,绘制圆点
3、判断点位数组长度是否大于1,时则需要以此连接点位,并将首尾点位相连,闭合路径
4、判断点位数组长度是否大于等于3,是则进行区域绘制
html及js片段:
<canvas
id="myCanvas"
ref="canvasRef"
:height="canvasHeight"
:width="canvasWidth"
>
let areaCtx = null;
let areaPoints = [];
const handelCanvas = () => {
var canvas = document.getElementById("myCanvas");
areaCtx = canvas.getContext("2d");
canvas.addEventListener("click", (e) => {
var rect = canvas.getBoundingClientRect();
var x = e.clientX - rect.left; // 转换为相对于canvas的位置
var y = e.clientY - rect.top;
//保存每次点击的点位
areaPoints.push({
x: x,
y: y,
});
//绘制方法
drawNewPoint();
});
};
const clearCanvas = () => {
areaCtx.clearRect(0, 0, canvasWidth, canvasHeight);
};
const drawNewPoint = () => {
clearCanvas();
areaCtx.fillStyle = "rgba(0, 0, 255, 0.5)";
//绘制点位
areaPoints.map((item) => {
areaCtx.beginPath();
areaCtx.arc(item.x, item.y, 5, 0, 2 * Math.PI);
areaCtx.fill();
});
//点位数量大于1时,需连接各个点位
if (areaPoints.length > 1) {
areaCtx.beginPath();
areaCtx.strokeStyle = "blue";
areaPoints.map((item, index) => {
if (index != 0) {
areaCtx.moveTo(areaPoints[index - 1].x, areaPoints[index - 1].y);
areaCtx.lineTo(item.x, item.y);
}
});
//首位点位相连,闭合路径
areaCtx.lineTo(areaPoints[0].x, areaPoints[0].y);
areaCtx.stroke();
}
if (areaPoints.length < 3) return;
//点位数量在3个及以上时,需要闭合框选区域,及填充区域
areaCtx.globalAlpha = 0.5;
areaCtx.beginPath();
areaCtx.moveTo(areaPoints[0].x, areaPoints[0].y);
areaPoints.forEach(({ x, y }) => {
areaCtx.lineTo(x, y);
});
areaCtx.closePath();
areaCtx.fill();
};
效果如下: