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中的CheckBox、RadioButton、DropDownList的取值赋值实现代码
Oct 12 Javascript
js通过googleAIP翻译PHP系统的语言配置的实现代码
Oct 17 Javascript
编写js扩展方法判断一个数组中是否包含某个元素
Nov 08 Javascript
Jquery 监视按键,按下回车键触发某方法的实现代码
May 11 Javascript
Javascript模拟加速运动与减速运动代码分享
Dec 11 Javascript
简介JavaScript中getUTCMonth()方法的使用
Jun 10 Javascript
Angularjs中UI Router全攻略
Jan 29 Javascript
浅谈js数组和splice的用法
Dec 04 Javascript
JavaScript转换数据库DateTime字段类型方法
Jun 27 Javascript
angularjs通过过滤器返回超链接的方法
Oct 26 Javascript
一步一步实现Vue的响应式(对象观测)
Sep 02 Javascript
JavaScript实现图片伪异步上传过程解析
Apr 10 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
xajax写的留言本
2006/11/25 PHP
php 网页游戏开发入门教程一(webgame+design)
2009/10/26 PHP
在项目中寻找代码的坏命名
2012/07/14 PHP
php简单实现批量上传图片的方法
2016/05/09 PHP
PDO的安全处理与事物处理方法
2016/10/31 PHP
laravel框架添加数据,显示数据,返回成功值的方法
2019/10/11 PHP
php字符串函数 str类常见用法示例
2020/05/15 PHP
javascript[js]获取url参数的代码
2007/10/17 Javascript
Javascript的数组与字典用法与遍历对象的属性技巧
2012/11/07 Javascript
基于JavaScript实现生成名片、链接等二维码
2015/09/20 Javascript
JQuery ztree 异步加载实例讲解
2016/02/25 Javascript
jQuery 全选 全部选 反选 实现代码
2016/08/17 Javascript
JS实现重新加载当前页面或者父页面的几种方法
2016/11/30 Javascript
通过AngularJS实现图片上传及缩略图展示示例
2017/01/03 Javascript
原生Javascript插件开发实践
2017/01/09 Javascript
微信小程序Echarts覆盖正常组件问题解决
2019/07/13 Javascript
微信小程序中button去除默认的边框实例代码
2019/08/01 Javascript
Angular利用HTTP POST下载流文件的步骤记录
2020/07/26 Javascript
JavaScript实现轮播图效果
2020/10/30 Javascript
[48:21]Mski vs VGJ.S Supermajor小组赛C组 BO3 第一场 6.3
2018/06/04 DOTA
python issubclass 和 isinstance函数
2019/07/25 Python
Python 动态导入对象,importlib.import_module()的使用方法
2019/08/28 Python
python代码打印100-999之间的回文数示例
2019/11/24 Python
python如何实现单链表的反转
2020/02/10 Python
Python递归求出列表(包括列表中的子列表)的最大值实例
2020/02/27 Python
Python无头爬虫下载文件的实现
2020/04/02 Python
利用Python如何实时检测自身内存占用
2020/05/09 Python
CSS3中的transform属性进行2D和3D变换的基本用法
2016/05/12 HTML / CSS
美国一家著名的儿童鞋制造商:Stride Rite
2017/01/02 全球购物
厂办主管岗位职责范本
2014/02/28 职场文书
中班开学寄语
2014/04/04 职场文书
集中整治工作方案
2014/05/01 职场文书
反腐倡廉标语
2014/06/24 职场文书
小学运动会报道稿
2014/10/04 职场文书
php+laravel 扫码二维码签到功能
2021/05/15 PHP
Python学习之包与模块详解
2022/03/19 Python