JS canvas实现画板和签字板功能


Posted in Javascript onFebruary 23, 2021

本文实例为大家分享了JS canvas实现画板/签字板功能的具体代码,供大家参考,具体内容如下

前言

常见的电子教室里的电子黑板。

本文特点:

原生JS
封装好的模块

最简代码样例

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Document</title>
</head>
<body>
 <canvas id="canvas"></canvas>
 <script>
 let c = document.getElementById('canvas');
 c.width = window.innerWidth;
 c.height = window.innerHeight;
 let ctx = c.getContext('2d');

 // draw one black board
 ctx.fillStyle = "black";
 ctx.fillRect(0,0,600,300);

 // 按下标记
 let onoff = false,
  oldx = -10,
  oldy = -10;

 // 设置颜色
 let linecolor = "white";

 // 设置线宽
 let linw = 4;

 // 添加鼠标事件
 // 按下
 c.addEventListener('mousedown', event => {
  onoff = true;
  // 位置 - 10是为了矫正位置,把绘图放在鼠标指针的顶端
  oldx = event.pageX - 10;
  oldy = event.pageY - 10;
 },false);
 // 移动
 c.addEventListener('mousemove', event => {
  if(onoff == true){
  let newx = event.pageX - 10,
   newy = event.pageY - 10;

  // 绘图
  ctx.beginPath();
  ctx.moveTo(oldx,oldy);
  ctx.lineTo(newx,newy);
  ctx.strokeStyle = linecolor;
  ctx.lineWidth = linw;
  ctx.lineCap = "round";
  ctx.stroke();
  // 每次移动都要更新坐标位置
  oldx = newx,
  oldy = newy;
  }
 }, true);
 // 弹起
 c.addEventListener('mouseup', ()=> {
  onoff = false;
 },false);
 </script>
</body>
</html>

结果展示

JS canvas实现画板和签字板功能

代码讲解

思路

1、鼠标按下,开始描画。鼠标按下事件。
2、鼠标弹起,结束描画。鼠标弹起事件。
3、鼠标按下移动,路径画线。鼠标移动事件。

代码讲解

整体思路:按下鼠标,触发移动的开关,移动后开始记录线条(用移动后的坐标-移动前的坐标,然后绘线),每次移动都会更新旧坐标。松开鼠标后,释放移动开关。

1、只有在鼠标按下,才会触发移动绘图的效果,所以需要增加一个状态判断。
2、因为鼠标指针和实际位置有一个偏移量,所以在坐标定位的时候,需要增加pagex-10从而使坐标位于指针的尖端处。
3、每次移动都要更新坐标位置,用小段的线段来模拟不规则的线。

封装模块

<canvas id="canvas"></canvas>
<script>
 class Board{
 constructor(canvasName = 'canvas', data = new Map([
  ["onoff", false],
  ["oldx", -10],
  ["oldy", -10],
  ["fillStyle", "black"],
  ["lineColor", "white"],
  ["lineWidth", 4],
  ["lineCap", "round"],
  ["canvasWidth", window.innerWidth],
  ["canvasHeight", window.innerHeight]
 ])){
  // this.data = data;
  this.c = document.getElementById(canvasName);
  this.ctx = this.c.getContext('2d');
  this.onoff = data.get("onoff");
  this.oldx = data.get("oldx");
  this.oldy = data.get("oldy");
  this.lineColor = data.get("lineColor");
  this.lineWidth = data.get("lineWidth");
  this.lineCap = data.get("lineCap");

  this.c.width = data.get("canvasWidth");
  this.c.height = data.get("canvasHeight");

  this.ctx.fillStyle = data.get("fillStyle");
  this.ctx.fillRect(0,0,600,300);
 }

 eventOperation(){
  // 添加鼠标事件
  // 按下
  this.c.addEventListener('mousedown', event => {
  this.onoff = true;
  // 位置 - 10是为了矫正位置,把绘图放在鼠标指针的顶端
  this.oldx = event.pageX - 10;
  this.oldy = event.pageY - 10;
  },false);
  // 移动
  this.c.addEventListener('mousemove', event => {
  if(this.onoff == true){
   let newx = event.pageX - 10,
   newy = event.pageY - 10;

   // 绘图
   this.ctx.beginPath();
   this.ctx.moveTo(this.oldx,this.oldy);
   this.ctx.lineTo(newx,newy);

   this.ctx.strokeStyle = this.lineColor;
   this.ctx.lineWidth = this.lineWidth;
   this.ctx.lineCap = this.lineCap;
   
   this.ctx.stroke();
   // 每次移动都要更新坐标位置
   this.oldx = newx,
   this.oldy = newy;
  }
  }, true);
  // 弹起
  this.c.addEventListener('mouseup', ()=> {
  this.onoff = false;
  },false);
 }

 }

 let board = new Board();
 board.eventOperation();
</script>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JS 添加千分位与去掉千分位的示例
Jul 11 Javascript
使用GruntJS链接与压缩多个JavaScript文件过程详解
Aug 02 Javascript
JavaScript中的prototype和constructor简明总结
Apr 05 Javascript
jquery ajax应用中iframe自适应高度问题解决方法
Apr 12 Javascript
javascript中sort()的用法实例分析
Jan 30 Javascript
jQuery调用ajax请求的常见方法汇总
Mar 24 Javascript
js实现无限级树形导航列表效果代码
Sep 23 Javascript
JavaScript实现点击按钮字体放大、缩小
Feb 29 Javascript
在JSP中如何实现MD5加密的方法
Nov 02 Javascript
JS库之Highlight.js的用法详解
Sep 13 Javascript
vue 获取元素额外生成的data-v-xxx操作
Sep 09 Javascript
JavaScript实现复选框全选和取消全选
Nov 20 Javascript
基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件功能
Feb 23 #Vue.js
js实现验证码干扰(动态)
Feb 23 #Javascript
js实现验证码干扰(静态)
Feb 22 #Javascript
JavaScript实现H5接金币功能(实例代码)
Feb 22 #Javascript
nestjs返回给前端数据格式的封装实现
Feb 22 #Javascript
NestJs使用Mongoose对MongoDB操作的方法
Feb 22 #Javascript
linux服务器快速卸载安装node环境(简单上手)
Feb 22 #Javascript
You might like
使用php实现截取指定长度
2013/08/06 PHP
PHP根据传入参数合并多个JS和CSS文件的简单实现
2014/06/13 PHP
PHP解压tar.gz格式文件的方法
2016/02/14 PHP
基于yaf框架和uploadify插件,做的一个导入excel文件,查看并保存数据的功能
2017/01/24 PHP
微信公众平台开发-微信服务器IP接口实例(含源码)
2017/03/05 PHP
php+ajax实现商品对比功能示例
2019/04/13 PHP
兼容FF和IE的动态table示例自写
2013/10/21 Javascript
JS获取各种浏览器窗口大小的方法
2014/01/14 Javascript
javascript中clone对象详解
2014/12/03 Javascript
jQuery获取当前点击的对象元素(实现代码)
2016/05/19 Javascript
javascript 中Cookie读、写与删除操作
2017/03/29 Javascript
Vuex之理解Getters的用法实例
2017/04/19 Javascript
js 发布订阅模式的实例讲解
2017/09/10 Javascript
JS实现同一DOM元素上onClick事件与onDblClick事件并存的解决方法
2018/06/07 Javascript
vue移动端下拉刷新和上拉加载的实现代码
2018/09/08 Javascript
vue-cli3+typescript初体验小结
2019/02/28 Javascript
nginx部署多个vue项目的方法示例
2020/09/06 Javascript
JavaScript实现拖动对话框效果的实现代码
2020/10/12 Javascript
在Python中操作字典之fromkeys()方法的使用
2015/05/21 Python
Python判断Abundant Number的方法
2015/06/15 Python
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
python3.7.0的安装步骤
2018/08/27 Python
python实现年会抽奖程序
2019/01/22 Python
Django重置migrations文件的方法步骤
2019/05/01 Python
在PYQT5中QscrollArea(滚动条)的使用方法
2019/06/14 Python
Python PyInstaller库基本使用方法分析
2019/12/12 Python
python 使用递归的方式实现语义图片分割功能
2020/07/16 Python
神经网络训练采用gpu设置的方式
2021/03/03 Python
东南亚冒险旅行与活动:Adventoro
2019/10/16 全球购物
AJAX的全称是什么
2012/11/06 面试题
机电专业个人自荐信格式模板
2013/09/23 职场文书
饭店工作计划书
2014/01/10 职场文书
渡河少年教学反思
2014/02/12 职场文书
党支部承诺书范文
2014/03/28 职场文书
医生个人年度总结
2015/02/28 职场文书
zabbix 代理服务器的部署与 zabbix-snmp 监控问题
2022/07/15 Servers