原生js使用canvas实现鼠标绘制直线

这篇具有很好参考价值的文章主要介绍了原生js使用canvas实现鼠标绘制直线。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

目录

一、原理

二、具体实现

(1)、创建画布

(2)、获取鼠标位置

(3)、创建线段类

(4)、创建主绘制类

(5)、绘制

(6)、效果图

 三、源代码

1、原生js

2、vue3实现 



一、原理

直线可以看成是一小段一小段的线段组成,并且两点确定一条直线;

首先当鼠标左键点击时候获取鼠标左键xy坐标,把当前获取得到的xy坐标赋值给线段起始点的坐标值,当鼠标移动后再获取新的鼠标位置x2和y2 再把获取得到到x2和y2赋值给线段的末尾点坐标值 ,之后两点连起来就是一段线段。之后再画一条线段,只要把前面那段线段的末尾点为起始点,再获取鼠标移动时候产生的新点,把两端相连就是一大段线段,如此重复。

canvas画线段:

          ctx.beginPath();//创建绘制路径
          ctx.moveTo(this.x,this.y);//第一个点
          ctx.lineTo(this.x2,this.y2); //第二个点
            
          ctx.strokeStyle="red" //设颜色
          ctx.stroke(); //开始绘制(把前面点连接)

二、具体实现

如果不熟悉canvas标签的话可以看我上篇博客

(1)、创建画布

<canvas width="600" height="400" id="mycancas">
  当前浏览器版本不支持,请升级
</canvas>

js获取画布

     var canvas=document.getElementById("mycancas");
      //得到画布的上下文,上下文有两个 2d和3d
      //所有的图形绘制都是通过ctx属性或者方法进行设置的,和canvas标签没有关系了
      var ctx=canvas.getContext("2d")

(2)、获取鼠标位置

创建鼠标工具类

   //记录鼠标的状态
      class MyMouseXy {
          // 鼠标左键按下的坐标  也是画线段的开始坐标
          static x;
          static y;
          //鼠标移动后的坐标  也是画线段的末端的坐标
          static x2;
          static y2;
          //鼠标左键是否弹起
        static ifmouseup=false;
      }

通过cavan画布内的鼠标事件获取鼠标坐标,鼠标点击画布时候牵扯到绘画,放在了后面。

    // 获取鼠标在画布移动的坐标
    canvas.addEventListener("mousemove", function(XY){
        MyMouseXy.x2=XY.offsetX;
        MyMouseXy.y2=XY.offsetY;
    })

    //鼠标左键弹起时候
    canvas.addEventListener("mouseup",function (XY){
        //鼠标状态修改成弹起
        console.log("鼠标弹起")
        MyMouseXy.ifmouseup=true;

    })

(3)、创建线段类

  //创建线段类  多个线段对象相互连接就成为了点
      class MyLine{
        x2;
        y2;
        //构造方法 设置第一个点
        constructor(x,y) {
          this.x=x;
          this.y=y;
        }
        //更新 设置第二点
        LineUpdata=function (x,y){

          this.x2=x;
          this.y2=y;
        }


        //绘制
        LineRraw=function (){
          ctx.beginPath();
          ctx.moveTo(this.x,this.y);//第一个点
          ctx.lineTo(this.x2,this.y2); //点三个

          ctx.strokeStyle="red" //设颜色
          ctx.stroke(); //开始绘制(把前面点连接)
            //这段线段绘制完成后 把当前线段的末尾点坐标赋值给下一段的起始点
            MyMouseXy.x=this.x2;
            MyMouseXy.y=this.y2;
        }

      }

(4)、创建主绘制类

为了结构更加工整 和可扩展性,我把绘制线段放到了一个类的方法中

 //主绘制类,想要填加跟多的绘制图形 只需要添加方法 或者改变MyRraw.Rae的指向即可
      class MyRraw{
            //用于扩展绘制其他图形的 raew
          static raew;
          //绘制直线的方法Rae
         static  Rae =function () {
             //通过监听器连续执行方法  把鼠标左键的点击时候的位置xy赋值给线段首点的坐标xy,再把鼠标移动后的点x2y2坐标赋值给线段末端点的坐标x2,y2 两点确定一条直线
              this.raew = setInterval(() => {
               //创建线段 把鼠标的点传入
                let myline=new MyLine(MyMouseXy.x,MyMouseXy.y);
                myline.LineUpdata(MyMouseXy.x2,MyMouseXy.y2);
                //当鼠标左键弹起时候停止绘制
                if(MyMouseXy.ifmouseup!=true) {
                    myline.LineRraw();
                }

              })
          }

      }

(5)、绘制

当鼠标点击时候调用主绘制类中的绘制方法执行绘制

  //画布鼠标监听 按下  按下后绘制图形
    canvas.addEventListener("mousedown",function (event){
        MyMouseXy.ifmouseup=false;

        //对于画线而言这是 鼠标按下时候获取
        MyMouseXy.x=event.offsetX;
        MyMouseXy.y=event.offsetY;



            //调用主绘制类的绘制直线的方法,绘制不同的图形只需要 动态修改 MyRraw.Rae();方法即可
            MyRraw.Rae();

    })

(6)、效果图

canvas鼠标画线,无聊的小程序,javascript,前端,html,html5

 三、源代码

1、原生js实现

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
  <style>
    canvas{
      /*  设置画布边框 以及外边距*/
      border: 1px solid;
      margin: 100px 0 0 100px;
    }
  </style>
</head>
<body>
<canvas width="600" height="400" id="mycancas">
  当前浏览器版本不支持,请升级
</canvas>
<button id="but1"> 清屏</button>
  <script>
      /**
       * 如果想要实现图形变换操作
       * 可以创建线段数组存储线段,对线段数组操作即可
       * @type {HTMLElement}
       */

    var canvas=document.getElementById("mycancas");
      //得到画布的上下文,上下文有两个 2d和3d
      //所有的图形绘制都是通过ctx属性或者方法进行设置的,和canvas标签没有关系了
      var ctx=canvas.getContext("2d")
     var but1=document.getElementById("but1");



         //创建线段类  多个线段对象相互连接就成为了点
      class MyLine{
        x2;
        y2;
        //构造方法设置第一个点
        constructor(x,y) {
          this.x=x;
          this.y=y;
        }
        //更新 设置第二给点
        LineUpdata=function (x,y){

          this.x2=x;
          this.y2=y;
        }


        //绘制
        LineRraw=function (){
          ctx.beginPath();
          ctx.moveTo(this.x,this.y);//第一个点
          ctx.lineTo(this.x2,this.y2); //点三个

          ctx.strokeStyle="red" //设颜色
          ctx.stroke(); //开始绘制(把前面点连接)
            //这段线段绘制完成后 把当前线段的末尾点坐标赋值给下一段的起始点
            MyMouseXy.x=this.x2;
            MyMouseXy.y=this.y2;
        }

      }

      //记录鼠标的状态
      class MyMouseXy {
          // 鼠标左键按下的坐标  也是画线段的开始坐标
          static x;
          static y;
          //鼠标移动后的坐标  也是画线段的末端的坐标
          static x2;
          static y2;
          //鼠标左键是否弹起
        static ifmouseup=false;
      }

    // 获取鼠标在画布移动的坐标
    canvas.addEventListener("mousemove", function(XY){
        MyMouseXy.x2=XY.offsetX;
        MyMouseXy.y2=XY.offsetY;
    })

    //鼠标左键弹起时候
    canvas.addEventListener("mouseup",function (XY){
        //鼠标状态修改成谈起
        console.log("鼠标弹起")
        MyMouseXy.ifmouseup=true;

    })


    //主绘制类,想要填加跟多的绘制图形 只需要添加方法 或者改变MyRraw.Rae的指向即可
      class MyRraw{
          static raew;
          //绘制直线的方法Rae
         static  Rae =function () {
             //通过监听器连续执行方法  把鼠标左键的点击时候的位置xy赋值给线段首点的坐标xy,再把鼠标移动后的点x2y2坐标赋值给线段末端点的坐标x2,y2 两点确定一条直线
              this.raew = setInterval(() => {
               //创建线段 把鼠标的点传入
                let myline=new MyLine(MyMouseXy.x,MyMouseXy.y);
                myline.LineUpdata(MyMouseXy.x2,MyMouseXy.y2);
                //当鼠标左键弹起时候停止绘制
                if(MyMouseXy.ifmouseup!=true) {
                    myline.LineRraw();
                }

              })
          }

      }


    //画布鼠标监听 按下  按下后绘制图形
    canvas.addEventListener("mousedown",function (event){
        MyMouseXy.ifmouseup=false;

        //对于画线而言这是 鼠标按下时候获取
        MyMouseXy.x=event.offsetX;
        MyMouseXy.y=event.offsetY;



            //调用主绘制类的绘制直线的方法,绘制不同的图形只需要 动态修改 MyRraw.Rae();方法即可
            MyRraw.Rae();

    })


        //当 “清屏按钮被点击”
        but1.onclick=function (){
            console.log("被点击")
            ctx.clearRect(0,0,canvas.width,canvas.height);
          //  ctx.clearRect(0,0,100,100);
        }

</script>
</body>
</html>

2、vue3实现 

<template>
<!--  画布-->


  <div  class="Mydiv">

    <canvas width="880" height="450" ref="canvas"  @mousedown="MouDown" @mousemove="MouMove" @mouseup="isDraw=false" @mouseleave="isDraw=false">
      浏览器版本过低,不支持canvas
    </canvas>

  </div>
<!--  <el-button type="danger" @click="clear">清除</el-button>-->
</template>

<script>
import {getCurrentInstance, onMounted, reactive,ref} from 'vue'
export default {
  name: "MyCanvas",
  setup(){
    //定义获取节点

    const canvas=ref(null);
    let ctx=ref(null);
    //用于捕捉是否绘画
    let isDraw=ref(false);

    //存储绘画线段的数据
    //点
    let pointes=reactive({
      frst:{x:'',y:''}, //第一给点
      allpointe:[],//全部
      last:{x:'',y:''} //最后一个点
        }
    );
    //线 //便于变形操作
    let Lines=reactive([]);

    //鼠标按下
  function MouDown(mou) {
    isDraw.value=true;
    let point={x:'',y:''};
      //第一个点(画线)
        point.x=mou.offsetX;
        point.y=mou.offsetY;
        //
    pointes.frst.x=mou.offsetX;
    pointes.frst.y=mou.offsetY;
    pointes.allpointe.push(point);

   // ctx.value.fillRect(point.x,point.y,100,100);
  }

    //鼠标移动 具体绘画函数,
    function MouMove(mou) {

    if(isDraw.value==true) {
      let point = {x: '', y: ''};
      //保存鼠标移动的点
      point.x = mou.offsetX;
      point.y = mou.offsetY;

      //下一个点(画线)
      pointes.last.x= mou.offsetX;
      pointes.last.y= mou.offsetY;


      //把点初始化
      pointes.allpointe.push(point);
      //画线
      lineDraw();
    }

    }

    //绘画
    function lineDraw(){

      ctx.value.beginPath();
      ctx.value.moveTo(pointes.frst.x,pointes.frst.y);

       ctx.value.lineTo(pointes.last.x,pointes.last.y)

     ctx.value.strokeStyle='red';
     ctx.value.stroke();

     //绘制结束后把下一个点给初始点
      pointes.frst.x=pointes.last.x;
      pointes.frst.y=pointes.last.y;

    }

    //清屏
    function clear(){
      // /ctx.clearRect(x,y,w,h); // (擦除一个矩形范围)
      ctx.value.clearRect(0,0,800,450);
    }




    //初始化方法
    onMounted(()=>{
      //获取页面canvas绘画版本
      canvas.value=getCurrentInstance().refs.canvas;
      //获得画笔
      ctx.value=canvas.value.getContext("2d");
      //获取DOM节点
      console.log(canvas);
    //  lineDraw();

    })
    return{
      pointes,
      MouDown,
      isDraw,
      canvas,
      ctx,
      Lines,
      MouMove,
      lineDraw,
      clear
    }

  }
}
</script>

<style scoped>
canvas{
  border: 1px solid;
  position: absolute;
  top: 20px;
  left: 20px;
}
.Mydiv{
  width:  900px;
  height: 500px;
  border: 1px solid;
}


</style>




仅供学习交流,有错误请在评论区指出

觉得有用还请点个赞^_^文章来源地址https://www.toymoban.com/news/detail-522924.html

到了这里,关于原生js使用canvas实现鼠标绘制直线的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • VC++ 利用MFC的CWindowDC类实现画线功能 在桌面窗口中画线 绘制彩色线条

    利用MFC的CWindowDC类实现画线功能 先介绍一个MFC类:CWindowDC,这个类也派生于CDC类,并且在构造时调用GetWindowDC函数获得相应的设备描述表对象,在析构时调用ReleaseDC函数释放该设备描述对象所占用的资源。也就是说,当我们利用CWindowDC对象绘图时,也不需要显式地调用GetDC和

    2023年04月23日
    浏览(38)
  • Qt+opencv 鼠标画线实现几何图形识别并动态创建

    使用Qt + OpenCV实现,通过鼠标画线绘制几何图形,然后通过opencv进行图形轮廓识别,返回图形顶点,然后创建对应的几何图形添加到场景中。绘制使用QGraphics体系完成。 看效果图: 本文demo在这里 点击下载 环境: Qt5.15.2 + vs2019 64bit 支持图形:直线、圆、椭圆、矩形、三角形。

    2024年02月10日
    浏览(37)
  • 微信小程序中使用画布canvas实现动态心电图绘制

    大家好,我是雄雄。 近期,接了个项目,三端(小程序、PC、公众号)同步开发,PC端没的问题,以前一直做的就是PC端,但是小程序和公众号之前没有做过,只能通过这个项目,边做边学了。 人家都说小程序用原生的特别难,大部分都用 uniapp 开发,说是这个方便快捷,还能

    2024年02月09日
    浏览(32)
  • 原生Js Canvas去除视频绿幕背景

    注: 这里的去除视频背景并不是对视频文件进行操作去除背景 如果需要对视频扣除背景并导出可以使用 ffmpeg 等库,这里仅作播放用所以采用这种方法 由于uniapp中的canvas经过封装,且 uniapp 的 drawImage 无法绘制视频帧画面,因此uniapp中不适用 实现过程是将视频使用canvas逐帧截

    2024年02月09日
    浏览(35)
  • 使用opengl绘制茶壶并实现鼠标拖动

    难点如下:         坐标轴绘制             选定一个原点,将坐标轴正方向和反方向的俩个点进行连线,代码及效果如上图所示(本次程序中由于渲染原因,坐标轴颜色统一为棕色)         如何实现鼠标响应         OPENGL中封存有对鼠标进行相应的函数,

    2024年01月17日
    浏览(29)
  • 原生js实现网页淘宝产品展示效果,鼠标移入小图展示对应大图(事件委托、事件传播、冒泡机制)【含完整代码】

    淘宝网页产品展示模块如下: 当鼠标移入小图,在上方会相应地展示大图 当鼠标移入小图,在上方会相应地展示大图;且当鼠标移出,图片停留在移入时显示的图片,不会改变。 本文实现效果如下(鼠标移入即改变,不用点击): 定义图片列表,为列表添加鼠标移入事件

    2024年02月07日
    浏览(31)
  • 原生JS-鼠标拖动

    步骤: 1. 鼠标按下div。 2. 鼠标移动,div跟着移动 添加 draggable=\\\"true\\\" 就能拖动。然后记录位置。 这种方式简单的多,只需要添加属性,然后记录位置就行。 这个属性最常见的用法是把A元素,拖动到B容器中。 A移动前 A移动后 可以写点样式,用于显示隐藏div

    2024年02月04日
    浏览(26)
  • QT:鼠标画线(双画布)

    widget.h widget.cpp 结果

    2024年01月24日
    浏览(24)
  • cocos creator 鼠标画笔|画线

    cocos creator 版本使用 至少适配版本2.3.2以上 案例: 简要思路:MOUSE_MOVE事件和Graphics组件实现 前端也可以通过canvas和mousemove事件实现,原理一致 具体步骤如下: 1.添加节点Node 2.在Node节点上绑定 组件Graphics 3.添加下方脚本drawcontroll.ts 4.注意Node节点的锚点和位置(如果不想要这个

    2024年02月11日
    浏览(31)
  • 微信小程序使用canvas绘制网络图片,使用canvas将图片变成圆形

    以上的写法 会造成某些图标无法绘制上去, 解决方法是在网络图片中不断嵌套,先绘制大图片,再绘制小图片的顺序 网上说使用先下载到本地,再使用img.src加载,我尝试过还是不行 长用在海报,需要将用户的头像画到canvas图片上,如: 其原理就是在图片上面放一个圆

    2024年02月13日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包