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 相关文章推荐
javascript 进度条 实现代码
Jul 30 Javascript
div层的移动及性能优化
Nov 16 Javascript
JS上传前预览图片实例
Mar 25 Javascript
javascript深拷贝(deepClone)详解
Aug 24 Javascript
利用jsonp跨域调用百度js实现搜索框智能提示
Aug 24 Javascript
基于jQuery实现选项卡效果
Jan 04 Javascript
微信小程序-小说阅读小程序实例(demo)
Jan 12 Javascript
canvas绘图不清晰的解决方案
Feb 28 Javascript
分享19个JavaScript 有用的简写写法
Jul 07 Javascript
对node.js中render和send的用法详解
May 14 Javascript
layui 表单标签的校验方法
Sep 04 Javascript
vue.js使用v-model实现父子组件间的双向通信示例
Feb 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
谏山创故乡大分县日田市水坝将设立《进击的巨人》立艾伦、三笠以及阿尔敏的铜像!
2020/03/06 日漫
PHP 配置文件中open_basedir选项作用
2009/07/19 PHP
php for 循环语句使用方法详细说明
2010/05/09 PHP
php实现的农历算法实例
2015/08/11 PHP
js不是基础的基础
2006/12/24 Javascript
让iframe子窗体取父窗体地址栏参数(querystring)
2009/10/13 Javascript
ymPrompt的doHandler方法来实现获取子窗口返回值的方法
2010/06/25 Javascript
js函数中onmousedown和onclick的区别和联系探讨
2013/05/19 Javascript
jquery的选择器的使用技巧之如何选择input框
2013/09/22 Javascript
jquery ajax jsonp跨域调用实例代码
2013/12/11 Javascript
Javascript selection的兼容性写法介绍
2013/12/20 Javascript
jquery实现简易的移动端验证表单
2015/11/08 Javascript
原生 JS Ajax,GET和POST 请求实例代码
2016/06/08 Javascript
关于JavaScript限制字数的输入框的那些事
2016/08/14 Javascript
解决node.js安装包失败的几种方法
2016/09/02 Javascript
javascript基础知识之html5轮播图实例讲解(44)
2017/02/17 Javascript
原生javascript实现文件异步上传的实例讲解
2017/10/26 Javascript
加载 vue 远程代码的组件实例详解
2017/11/20 Javascript
vue中使用v-model完成组件间的通信
2019/08/22 Javascript
[00:31]DOTA2上海特级锦标赛 Fnatic战队宣传片
2016/03/04 DOTA
Python之eval()函数危险性浅析
2014/07/03 Python
Python基于PycURL实现POST的方法
2015/07/25 Python
python dataframe向下向上填充,fillna和ffill的方法
2018/11/28 Python
Python 面向对象静态方法、类方法、属性方法知识点小结
2020/03/09 Python
在pycharm中使用matplotlib.pyplot 绘图时报错的解决
2020/06/01 Python
python爬虫分布式获取数据的实例方法
2020/11/26 Python
四年的个人工作自我评价
2013/12/10 职场文书
公司年会晚宴演讲稿
2014/01/06 职场文书
大学生个人自荐信样本
2014/03/02 职场文书
充分就业社区汇报材料
2014/05/07 职场文书
募捐倡议书怎么写
2014/05/14 职场文书
小学生感恩老师演讲稿
2014/08/28 职场文书
教师自我剖析材料(群众路线)
2014/09/29 职场文书
2014幼儿园大班工作总结
2014/11/10 职场文书
社会实践心得体会范文
2016/01/14 职场文书
Redis可视化客户端小结
2021/06/10 Redis