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代码
Jan 01 Javascript
jquery $.ajax()取xml数据的小问题解决方法
Nov 20 Javascript
Javascript 页面模板化很多人没有使用过的方法
Jun 05 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
Oct 23 Javascript
jquery提交form表单简单示例分享
Mar 03 Javascript
javascript设置和获取cookie的方法实例详解
Jan 05 Javascript
windows下更新npm和node的方法
Nov 30 Javascript
浅谈AngularJs 双向绑定原理(数据绑定机制)
Dec 07 Javascript
基于zTree树形菜单的使用实例
Dec 25 Javascript
element ui table 增加筛选的方法示例
Nov 02 Javascript
解决layui-open关闭自身窗口的问题
Sep 10 Javascript
javascript中可能用得到的全部的排序算法
Mar 05 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 前一天或后一天的日期
2008/06/28 PHP
PHP实现长文章分页实例代码(附源码)
2016/02/03 PHP
PHP微信API接口类
2016/08/22 PHP
newxtree.js代码
2007/03/13 Javascript
jQuery html() in Firefox (uses .innerHTML) ignores DOM changes
2010/03/05 Javascript
使用jquery实现图文切换效果另加特效
2013/01/20 Javascript
sencha touch 模仿tabpanel导航栏TabBar的实例代码
2013/10/24 Javascript
window.open()详解及浏览器兼容性问题示例探讨
2014/05/29 Javascript
基于javascript实现漂亮的页面过渡动画效果附源码下载
2015/10/26 Javascript
使用JavaScript实现ajax的实例代码
2016/05/11 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图的组合双轴图效果示例【附demo源码下载】
2017/03/09 Javascript
微信小程序 数据遍历的实现
2017/04/05 Javascript
微信小程序methods中定义的方法互相调用的实例代码
2018/08/07 Javascript
微信小程序开发之路由切换页面重定向问题
2018/09/18 Javascript
vue实现自定义日期组件功能的实例代码
2018/11/06 Javascript
详解微信小程序框架wepy踩坑记录(与vue对比)
2019/03/12 Javascript
vue-cli 为项目设置别名的方法
2019/10/15 Javascript
解决vue单页面多个组件嵌套监听浏览器窗口变化问题
2020/07/30 Javascript
vue 项目软键盘回车触发搜索事件
2020/09/09 Javascript
Python写的一个简单DNS服务器实例
2014/06/04 Python
Python类方法__init__和__del__构造、析构过程分析
2015/03/06 Python
Python操作mysql数据库实现增删查改功能的方法
2018/01/15 Python
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
2018/03/19 Python
python3+PyQt5实现拖放功能
2018/04/24 Python
对python列表里的字典元素去重方法详解
2019/01/21 Python
python实现共轭梯度法
2019/07/03 Python
Python 线程池用法简单示例
2019/10/02 Python
为什么说python更适合树莓派编程
2020/07/20 Python
使用CSS3制作饼状旋转载入效果的实例
2015/06/23 HTML / CSS
html5本地存储_动力节点Java学院整理
2017/07/12 HTML / CSS
行政主管岗位职责
2013/11/18 职场文书
优秀士兵先进事迹
2014/02/06 职场文书
商铺租赁意向书
2014/04/01 职场文书
数学教研活动总结
2014/07/02 职场文书
法制教育演讲稿
2014/09/10 职场文书
工伤死亡理赔协议书
2014/10/20 职场文书