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判断生效时间不得大于失效时间的思路及代码
Apr 23 Javascript
jquery easyui 对于开始时间小于结束时间的判断示例
Mar 22 Javascript
分享10个原生JavaScript技巧
Apr 20 Javascript
jQuery实现简单的文件上传进度条效果
Mar 26 Javascript
Jquery调用iframe父页面中的元素及方法
Aug 23 Javascript
Bootstrap分页插件之Bootstrap Paginator实例详解
Oct 15 Javascript
JavaScript ES6中CLASS的使用详解
Nov 22 Javascript
bootstrap警告框示例代码分享
May 17 Javascript
35个最好用的Vue开源库(史上最全)
Jan 03 Javascript
微信小程序开发摇一摇功能
Nov 22 Javascript
不刷新网页就能链接新的js文件方法总结
Mar 01 Javascript
Quasar Input:type=&quot;number&quot; 去掉上下小箭头 实现加减按钮样式功能
Apr 09 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
全国FM电台频率大全 - 31 新疆维吾尔族自治区
2020/03/11 无线电
PHP验证码类代码( 最新修改,完全定制化! )
2010/12/02 PHP
php XPath对XML文件查找及修改实现代码
2011/07/27 PHP
PHP遍历XML文档所有节点的方法
2015/03/12 PHP
PHP实现的多维数组排序算法分析
2018/02/10 PHP
php把文件设置为插件的技巧方法
2020/02/03 PHP
JavaScript的类型简单说明
2010/09/03 Javascript
js修改table中Td的值(定义td的双击事件)
2013/01/10 Javascript
JS实现商品倒计时实现代码
2013/05/03 Javascript
js实现绿白相间竖向网页百叶窗动画切换效果
2015/03/02 Javascript
JQuery radio(单选按钮)操作方法汇总
2015/04/15 Javascript
对Angular.js Controller如何进行单元测试
2016/10/25 Javascript
微信小程序 石头剪刀布实例代码
2017/01/04 Javascript
详解百度百科目录导航树小插件
2017/01/08 Javascript
AngularJS 仿微信图片手势缩放的实例
2017/09/28 Javascript
解决vue中使用swiper插件问题及swiper在vue中的用法
2018/04/04 Javascript
解决vue初始化项目时,一直卡在Project description上的问题
2019/10/31 Javascript
理解生产者消费者模型及在Python编程中的运用实例
2016/06/26 Python
Unicode和Python的中文处理
2017/03/19 Python
python出现&quot;IndentationError: unexpected indent&quot;错误解决办法
2017/10/15 Python
TF-IDF与余弦相似性的应用(二) 找出相似文章
2017/12/21 Python
Python和Go语言的区别总结
2019/02/20 Python
python实现对服务器脚本敏感信息的加密解密功能
2019/08/13 Python
Python实现的微信红包提醒功能示例
2019/08/22 Python
Python编译成.so文件进行加密后调用的实现
2019/12/23 Python
Python面向对象之继承原理与用法案例分析
2019/12/31 Python
Python实现验证码识别
2020/06/15 Python
深入了解Python enumerate和zip
2020/07/16 Python
python破解同事的压缩包密码
2020/10/14 Python
使用CSS3的背景渐变Text Gradient 创建文字颜色渐变
2014/08/19 HTML / CSS
html5在移动端的屏幕适应问题示例探讨
2014/06/15 HTML / CSS
使用C#编写创建一个线程的代码
2013/01/22 面试题
Exception类的常用方法
2012/06/16 面试题
大学生自我鉴定范文模板
2014/01/21 职场文书
节能减排倡议书
2014/04/15 职场文书
党的群众路线教育实践活动对照检查材料思想汇报(党员篇)
2014/09/25 职场文书