vue canvas自由框选区域

核心步骤:鼠标每次拾取点位后,将点位保存到点位数组中,调用绘制方法。
绘制方法逻辑如下:
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();
};

效果如下:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值