基于html5 canvas做批改作业的小插件


Posted in HTML / CSS onMay 20, 2020

今天公司有一个新的需求,就是要在返回的作业照片里面可以涂鸦批改,批改完后就连同批改后的照片上传到服务器。这对我不怎么熟悉canvas的人来说是个挑战。

需求分析

  1. 能进行批改,就是相当于画笔
  2. 能进行画笔的撤回功能
  3. 能进行全部画笔的清除功能
  4. 可以转化画笔的颜色

技术上的实现思路

  在听到这需求后的第一反应就是用canvas来做,所以我在w3school阅读了 canvas的API .

1.将图片转到canvas,用到API: drawImage()

2画笔的实现

  • 当按下鼠标(mousedown)记录开始点startX, startY
  • 当移动鼠标的时候(mousemove)就获取当前的鼠标的坐标e.clientX, e.clientY,获取到了当前的坐标后,与上一个点的坐标轴的左边进行连线(lineTo ),这样就能画出了一条横线了
  • 当鼠标松开左键(mouseup)时候,就清除mousemove的函数

3.清除功能:讲原始的图片再次用drawImage()函数来重置
4.撤回功能:在每次按下鼠标那时候,用getImageData()函数获取当前的图像记录到数组里面,然后按撤回则使用putImageData()函数放在canvas
5.画笔的颜色:在mousemove里面改变strokeStyle笔的颜色

代码实现

移动鼠标画出线条的代码

let self = this;
    this.canvasNode = document.createElement('canvas');
    let styleString = this.utils.formatStyle(CANVAS_STYLE); // CANVAS_STYLE是canvas的样式
    this.canvasNode.setAttribute('id','canvas');
    // 一定要设置这width 和 height
    let ratio = this.imgNode.width / this.imgNode.height, height = this.imgNode.height, width = this.imgNode.width;
    let tempWidth , tempHeight;
    // 按比例伸缩
    if(ratio >= window.innerWidth / window.innerHeight){
      if(width > window.innerWidth){
        tempWidth = window.innerWidth;
        tempHeight = height * window.innerWidth / width;
      } else {
        tempWidth = width;
        tempHeight = height;
      }
    }else{
      if(height > window.innerHeight){
        tempWidth = width * window.innerHeight / width;
        tempHeight = window.innerHeight;
      }else{
        tempWidth = width;
        tempHeight = height;
      }
    }
    this.canvasNode.height = tempHeight;
    this.canvasNode.width = tempWidth;
    styleString = Object.assign({'width': tempWidth, 'height': tempHeight}, CANVAS_STYLE);
    this.canvasNode.setAttribute('style', styleString);

    let ctx = this.canvasNode.getContext('2d'), startX = 0, startY = 0;
    let image = new Image() ;
    image.setAttribute("crossOrigin",'Anonymous')
    // 加时间戳因为这图片的域名没设置跨域https://www.jianshu.com/p/c3aa975923de
    image.src = this.imgNode.src + '?t=' + new Date().getTime(); 
    image.height = tempHeight;
    image.width = tempWidth;
    image.onload = function(){
      ctx.drawImage(image, 0, 0, tempWidth, tempHeight);
    }
    // 鼠标移动事件
    let mousemoveFn = function(e) {
      ctx.beginPath();
      ctx.lineWidth = 3;
      ctx.strokeStyle = self.currentColor;
      if(startX == e.clientX - self.canvasNode.offsetLeft || startY ===  e.clientY - self.canvasNode.offsetTop  ) return
      ctx.moveTo(startX,startY);
      ctx.lineTo(e.clientX - self.canvasNode.offsetLeft , e.clientY - self.canvasNode.offsetTop );
      ctx.stroke();
      startX = e.clientX - self.canvasNode.offsetLeft;
      startY = e.clientY - self.canvasNode.offsetTop ; // 37是header的高度
    }
    // 鼠标按下事件
    this.canvasNode.addEventListener("mousedown",function(e){
      startX = e.clientX - self.canvasNode.offsetLeft;
      startY = e.clientY - self.canvasNode.offsetTop ;

      // 如果在mouseup那里记录 则在撤回时候要做多一个步骤
      let imageData = ctx.getImageData(0,0, self.canvasNode.width, self.canvasNode.height);
      self.imageDataArray.push(imageData); // 这imageDataArray用来记录画笔的笔画
      self.canvasNode.addEventListener("mousemove", mousemoveFn, false);
    },false);
    this.canvasNode.addEventListener('mouseup', function(e){
      self.canvasNode.removeEventListener('mousemove', mousemoveFn);
    });
    this.bgNode.appendChild(this.canvasNode);

遇到的问题

1.图片的跨域问题   因为这个域名只设置了192.168.6.*的跨域,所以我localhost的域名会报跨域的问题(只对192.168.6.*的跨域是同事告诉我的,不然我还在傻乎乎的查问题)

解决办法:设置vue.congfig.js文件的dev下的host

2.图片的按比例伸缩完按保存后图片的尺寸变了   我用toDataURL()方法输出的base64后的图片尺寸变了。原因:在我把图片draw上canvas上时候,用了上面代码的图片那比例伸缩的算法把图片变小了,所以画在canvas上的图片也变小了...

解决办法:(待解决)

总结

  • 第一次接触canvas与图片相结合的功能,让我熟悉了canvas的api
  • 在遇到没做过的功能之前,一定要先定下心来运用你所知道的知识思考下有没可行的方法,找到了突破点就可以做了
  • 在你碰上不熟悉的知识时候,一定要先看api,我这canvas之前不怎么会的,之后我细看了几遍的api,我就可以上手去做功能了,并且在w3school看到的例子让我觉得canvas真的很强大

到此这篇关于基于html5 canvas做批改作业的小插件的文章就介绍到这了,更多相关canvas 批改作业插件内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

HTML / CSS 相关文章推荐
详解css3自定义滚动条样式写法
Dec 25 HTML / CSS
CSS3 倾斜的网页图片库实例教程
Nov 14 HTML / CSS
css3的transition效果和transfor效果示例介绍
Oct 30 HTML / CSS
html5新增的属性和废除的属性简要概述
Feb 20 HTML / CSS
HTML5画渐变背景图片并自动下载实现步骤
Nov 18 HTML / CSS
HTML5中5个简单实用的API
Apr 28 HTML / CSS
详解canvas绘图时遇到的跨域问题
Mar 22 HTML / CSS
解析html5 canvas实现背景鼠标连线动态效果代码
Jun 17 HTML / CSS
五分钟学会HTML5的WebSocket协议
Nov 22 HTML / CSS
AmazeUI 导航条的实现示例
Aug 14 HTML / CSS
详解CSS玩转图片Base64编码
May 25 HTML / CSS
详解CSS伪元素的妙用单标签之美
May 25 HTML / CSS
video下autoplay属性无效的解决方法(添加muted属性)
May 19 #HTML / CSS
html2canvas生成的图片偏移不完整的解决方法
May 19 #HTML / CSS
html5简介及新增功能介绍
May 18 #HTML / CSS
Html5让容器充满屏幕高度或自适应剩余高度的布局实现
May 14 #HTML / CSS
Html5在手机端调用相机的方法实现
May 13 #HTML / CSS
Html5页面获取微信公众号的openid的方法
May 12 #HTML / CSS
钉钉企业内部H5微应用开发详解
May 12 #HTML / CSS
You might like
PHP 魔术变量和魔术函数详解
2015/02/25 PHP
return false,对阻止事件默认动作的一些测试代码
2010/11/17 Javascript
js实现获取焦点后光标在字符串后
2014/09/17 Javascript
一个JavaScript函数把URL参数解析成Json对象
2014/09/24 Javascript
简单介绍JavaScript数据类型之隐式类型转换
2015/12/28 Javascript
JavaScript中定时控制Throttle、Debounce和Immediate详解
2016/11/17 Javascript
vue.js加载新的内容(实例代码)
2017/06/01 Javascript
JavaScript基础之this详解
2017/06/04 Javascript
纯JS实现可用于页码更换的飞页特效示例
2018/05/21 Javascript
koa socket即时通讯的示例代码
2018/09/07 Javascript
使用Node.js实现一个多人游戏服务器引擎
2019/03/13 Javascript
Vue+Java 通过websocket实现服务器与客户端双向通信操作
2020/09/22 Javascript
[46:27]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第一局
2016/03/02 DOTA
[01:12:53]完美世界DOTA2联赛PWL S2 Forest vs SZ 第一场 11.25
2020/11/26 DOTA
python 字典中文key处理,读取,比较方法
2018/07/06 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
对Python中创建进程的两种方式以及进程池详解
2019/01/14 Python
从列表或字典创建Pandas的DataFrame对象的方法
2019/07/06 Python
python 获取sqlite3数据库的表名和表字段名的实例
2019/07/17 Python
python2.7实现复制大量文件及文件夹资料
2019/08/31 Python
SELENIUM自动化模拟键盘快捷键操作实现解析
2019/10/28 Python
原来我一直安装 Python 库的姿势都不对呀
2019/11/11 Python
Python处理mysql特殊字符的问题
2020/03/02 Python
如何查看浏览器对html5的支持情况
2020/12/15 HTML / CSS
adidas官方旗舰店:德国运动用品制造商
2017/11/25 全球购物
意大利制造的男鞋和女鞋:SCAROSSO
2018/03/07 全球购物
GafasWorld西班牙:购买太阳镜、眼镜和隐形眼镜
2019/09/08 全球购物
招商专员岗位职责
2014/02/08 职场文书
安全例会汇报材料
2014/08/23 职场文书
2014年协会工作总结
2014/11/22 职场文书
邀请函范文
2015/02/02 职场文书
2015年社区统计工作总结
2015/04/21 职场文书
超搞笑婚前保证书
2015/05/08 职场文书
道士塔读书笔记
2015/06/30 职场文书
MongoDB支持的数据类型
2022/04/11 MongoDB
vue二维数组循环嵌套方式 循环数组、循环嵌套数组
2022/04/24 Vue.js