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 相关文章推荐
学习jquery必备 api中英文对照的chm手册 下载
May 03 Javascript
javascript之通用简单的table选项卡实现(二)
May 09 Javascript
js内存泄露的几种情况详细探讨
May 31 Javascript
js 为label标签和div标签赋值的方法
Aug 08 Javascript
js加载之使用DOM方法动态加载Javascript文件
Nov 08 Javascript
浅谈JavaScript实现面向对象中的类
Dec 09 Javascript
JavaScript错误处理
Feb 03 Javascript
jQuery实现的超链接提示效果示例【附demo源码下载】
Sep 09 Javascript
JS jQuery使用正则表达式去空字符的简单实现代码
May 20 jQuery
聊聊Vue.js的template编译的问题
Oct 09 Javascript
vue和小程序项目中使用iconfont的方法
May 19 Javascript
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
Jan 08 Vue.js
基于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 文件缓存函数
2011/10/08 PHP
PHP定时执行计划任务的多种方法小结
2011/12/19 PHP
php实现面包屑导航例子分享
2015/12/19 PHP
IE和FireFox(FF)中js和css的不同
2009/04/13 Javascript
JavaScript 高级篇之闭包、模拟类,继承(五)
2012/04/07 Javascript
node.js调用C++开发的模块实例
2015/07/03 Javascript
最全的Javascript编码规范(推荐)
2016/06/22 Javascript
jQuery 中ajax异步调用的四种方式
2016/06/28 Javascript
jQuery子元素过滤选择器用法示例
2016/09/09 Javascript
JS中with的替代方法与String中的正则方法详解
2016/12/23 Javascript
Vue中img的src属性绑定与static文件夹实例
2017/05/18 Javascript
彻底搞懂JavaScript中的apply和call方法(必看)
2017/09/18 Javascript
小程序图片剪裁加旋转的示例代码
2018/07/10 Javascript
详解如何用typescript开发koa2的二三事
2018/11/13 Javascript
微信小程序城市选择及搜索功能的方法
2019/03/22 Javascript
python 筛选数据集中列中value长度大于20的数据集方法
2018/06/14 Python
python3解析库pyquery的深入讲解
2018/06/26 Python
详解python实现识别手写MNIST数字集的程序
2018/08/03 Python
python使用webdriver爬取微信公众号
2018/08/31 Python
Scrapy框架爬取Boss直聘网Python职位信息的源码
2019/02/22 Python
Python字符串通过'+'和join函数拼接新字符串的性能测试比较
2019/03/05 Python
python 字段拆分详解
2019/12/17 Python
解决PyCharm不在run输出运行结果而不是再Console里输出的问题
2020/09/21 Python
深入解析HTML5使用SVG图像时的viewBox属性用法
2015/09/02 HTML / CSS
浅析移动设备HTML5页面布局
2015/12/01 HTML / CSS
台湾时尚彩瞳专门店:imeime
2019/08/16 全球购物
电影T恤、80年代T恤和80年代服装:TV Store Online
2020/01/05 全球购物
养殖项目策划书范文
2014/01/13 职场文书
网上快餐厅创业计划书
2014/02/01 职场文书
先进工作者获奖感言
2014/02/08 职场文书
百年校庆节目主持词
2014/03/27 职场文书
2014年领导班子工作总结
2014/12/11 职场文书
交通事故和解协议书
2015/01/27 职场文书
2015年个人实习工作总结
2015/05/28 职场文书
MySQL 分页查询的优化技巧
2021/05/12 MySQL
Redis+Lua脚本实现计数器接口防刷功能(升级版)
2022/02/12 Redis