canvas 鼠标点击绘制任意多边形、鼠标拖动改变形状


前言

本文主要介绍如何通过鼠标点击绘制任意多边形,以及通过鼠标移动改变多边形的形状

一、通用代码封装

 class Point {
    constructor(opts = {}) {
         this.x = opts.x || 0;
         this.y = opts.y || 0;
     }
 }
const CanvasUtils = {
 // 获取在dom元素上点击的坐标
  getPointOnEle(e) {
      e = e || window.event;
      return new Point({
          x: e.offsetX,
          y: e.offsetY
      });
  },
}

二、canvas类的封装

1.定义类

class CanvasServer {
  constructor(opts) {
       // 画布
       this.canvas = null;
       // 画布上下文
      this.ctx = null;
      // 存放绘制的点
      this.pointList = [];
       
      // 圆点的定义
      this.arcInfo = {
          radius : 8,
          curPointColor : '#ff0000',
          pointColor : 'blue'
      }
      
      // 当前点是否存在
      this.isPointExist = false;
      
      // 当前移动点的坐标
      this.curMovePoint = {};   
      
      // 当前移动点的下标
      this.curMovePointIndex = 0;   

       // 初始化canvas
      this._init(opts);
      
      // 初始化鼠标事件
      this._initCanvasEvent();
  }
  ...
   global.CanvasServer = CanvasServer;

})(this);

2.初始化

   _init(opts){
        this.canvas = opts.canvas;
        this.canvas.width = opts.width;
        this.canvas.height = opts.height;
        this.ctx = this.canvas.getContext(`2d`);
    }

3.初始化鼠标事件

 _initCanvasEvent(){
    EventUtil.addHandler(this.canvas, `mousedown`, this._handleMouseDown, this);

     EventUtil.addHandler(this.canvas, `mousemove`, this._handleMouseMove, this);

     EventUtil.addHandler(this.canvas, `mouseup`, this._handleMouseUp, this);
 }

3.鼠标事件处理

// 鼠标按下
_handleMouseDown(e){
     e = e || window.event;
     const point = CanvasUtils.getPointOnEle(e, this.canvas);
     
     for(let index = 0 ; index < this.pointList.length ; index++){
         let item = this.pointList[index];
         if (Math.abs(item.x - point.x) < this.arcInfo.radius && Math.abs(item.y - point.y) < this.arcInfo.radius) {
             this.isPointExist = true;
             this.curMovePoint = item;
             this.curMovePointIndex = index;
             return;
         }
     }
     this.isPointExist = false;
     this.pointList.push(point);
     this._drawPolygon();
     this._drawKeyPoints();
 }
        
 // 鼠标移动
 _handleMouseMove(e){
     // 如果没有选中关键点,则直接返回
     if(!this.isPointExist){
        return;
     }
     e = e || window.event;
     const point = CanvasUtils.getPointOnEle(e, this.canvas);
     
     this.pointList.splice(this.curMovePointIndex,1,point);
     
     this._drawPolygon();
     this._drawKeyPoints();
 }

 // 鼠标按起
 _handleMouseUp(e){
     this.isPointExist = false;
     this.curMovePoint = {};
     this.curMovePointIndex = 0;
 }

4.绘制多边形及顶点

// 绘制多边形
_drawPolygon(){
     this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
     this.ctx.strokeStyle = '#000';
     this.ctx.beginPath();
     this.ctx.moveTo(this.pointList[0].x,this.pointList[0].y);
     for(var i=1;i<this.pointList.length;i++) {
       this.ctx.lineTo(this.pointList[i].x,this.pointList[i].y);
     }
     this.ctx.closePath();
     this.ctx.stroke();

 }

 // 绘制鼠标点击的关键点
 _drawKeyPoints(){
     if(this.pointList.length === 0){
         return;
     }
     
     let pointList = this.pointList.slice(0);
     
     // 如果是移动关键点,则点绘制统一的颜色
     if(!this.isPointExist){
         let curPoint = pointList.pop();
         // 绘制当前点
         this._drawArc(curPoint.x,curPoint.y,this.arcInfo.curPointColor);
     }

     pointList.forEach(item => {
         this._drawArc(item.x,item.y,this.arcInfo.pointColor);
     });
 }

 // 绘图圆点
 _drawArc(x,y,color){
     this.ctx.beginPath();
     this.ctx.fillStyle = color;
     this.ctx.arc(x,y,this.arcInfo.radius,0,2 * Math.PI, false);
     this.ctx.fill();
     this.ctx.closePath();
 }

5.调用方式


 <canvas id="myCanvas"></canvas>

 <script type="text/javascript">
     window.onload = function() {
         drawCanvas();
     }

     function drawCanvas() {
        var canvas = document.getElementById("myCanvas");
            canvas.width = document.body.clientWidth;
            canvas.height = document.body.clientHeight;
         
         var width = document.body.clientWidth;
         var height = document.body.clientHeight;
         
         new CanvasServer({
             canvas,
             width,
             height,
         });
     }
 </script>

效果图

在这里插入图片描述
在这里插入图片描述

  • 7
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
canvas中使用鼠标绘制直线的过程如下所示: 1. 首先,通过鼠标事件监听器获取鼠标在画布上移动时的坐标。这可以通过添加mousemove事件监听器来实现。在事件处理函数中,可以使用event对象的offsetX和offsetY属性来获取鼠标的坐标。\[3\] 2. 接下来,当鼠标点击画布时,可以通过添加mousedown事件监听器来触发绘制直线的操作。在事件处理函数中,可以获取鼠标点击时的坐标,并将其赋值给线段的起始点坐标。然后,调用主绘制类中的绘制方法来执行绘制操作。\[1\] 3. 在主绘制类中,可以定义一个绘制直线的方法Rae。该方法通过监听器连续执行,将鼠标左键点击时的位置坐标赋值给线段的起始点坐标,将鼠标移动后的位置坐标赋值给线段的末端点坐标。然后,创建一个线段对象,并调用其方法来更新线段的坐标和绘制直线。当鼠标左键弹起时,停止绘制直线。\[2\] 4. 最后,创建一个线段类,用于表示线段对象。该类包含构造方法用于设置线段的起始点坐标,以及更新方法和绘制方法用于更新线段的坐标和绘制直线。\[3\] 综上所述,通过监听鼠标事件和调用相应的方法,可以在canvas中实现鼠标绘制直线的功能。 #### 引用[.reference_title] - *1* *2* *3* [原生js使用canvas实现鼠标绘制直线](https://blog.csdn.net/weixin_72388638/article/details/130034235)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值