开发Canvas 绘画应用(二):实现绘画
开发Canvas 绘画应用(一):搭好框架 中我们已经把基本框架及基础功能实现了,现在要实现本应用的重点:绘画功能。
首先分析一下,我们要实现绘画,需要具备的理论知识如下:
(1)获取触摸点的坐标
类似于获取鼠标在屏幕上的位置,我们现在需要获取手指在绘图板上的位置,这就需要用到触摸事件的跟踪触摸的属性:
touches:表示当前跟踪的触摸操作的 Touch 对象的数组。targetTouches:特定于事件目标的 Touch 对象的数组。changedTouches:表示自上次触摸以来发生了什么改变的 Touch 对象的数组。
可以将有几个 Touch 对象看成有几个手指,每个手指的触摸点对应一系列属性。
注意:与
changedTouches不同,touches和targetTouches在touchend触发时均没有 Touch 数组,length为0,即触摸点数为0。可以在浏览器上打印输出进行对比。
其中,每个 Touch 对象包含下列属性:
- clientX:触摸目标在视口中的 x 坐标。
- clientY:触摸目标在视口中的 y 坐标。
- identifier:标识触摸的唯一 ID。
- pageX:触摸目标在页面中的 x 坐标。
- pageY:触摸目标在页面中的 y 坐标。
- screenX:触摸目标在屏幕中的 x 坐标。
- screenY:触摸目标在屏幕中的 y 坐标。
- target:触摸的 DOM 节点目标。
(2)Canvas 绘制路径的方法
beginPath():绘制路径前必须调用,表示要开始绘制新路径。lineTo(x,y):从上一点开始绘制一条直线。moveTo(x,y):从绘图游标开始移动到(x,y),不画线。closePath():创建路径之后,绘制一条连接到起点的线条。fill():对路径进行填充。stroke():对路径进行描边。clip():在路径上创建一个剪切区域。
绘画实现
OK,理论知识已经具备了,接下去就要开始搬砖了。
① 初始化数据
initData() {
this.lastX = 0;
this.lastY = 0;
this.isPaint = false;
return this;
}
② 实现绘画函数
/**
* 绘画函数
* @param {[type]} x 触摸点x坐标
* @param {[type]} y 触摸点y坐标
* @return {[type]} 将当前坐标赋给上一个点坐标
*/
draw(x, y) {
if (this.isPaint) {
this.ctx.beginPath(); // 开始绘制路径,必须调用
this.ctx.moveTo(this.lastX, this.lastY); // 将绘图游标移动到到上一点
this.ctx.lineTo(x, y); // 从上一点开始绘制一条到(x,y)的直线
this.ctx.stroke(); // 描边路径
}
// 上面必须判断 this.isPaint
// 当 'touchstart' 时,先移动到触摸点
this.lastX = x;
this.lastY = y;
}
③ 完善事件处理函数(★重点)
// 触摸事件处理函数
touchF(e) {
e.preventDefault(); // 阻止浏览器默认行为
const touches = e.changedTouches; // 获取 Touch 对象list
const point = touches[0]; // 获取第一个 Touch 对象
// 获取元素宽、高及距窗口上下左右距离
const rect = this.cva.getBoundingClientRect();
// 相当于const rect = $('.painter').offset();
// 相当于const rect = { left: this.cva.offsetLeft, top: this.cva.offsetTop }
switch (e.type) {
case 'touchstart':
// 获取触摸点的x,y坐标,传入draw函数
this.draw(point.clientX - rect.left, point.clientY - rect.top);
this.isPaint = true;
break;
case 'touchmove':
this.draw(point.clientX - rect.left, point.clientY - rect.top);
break;
case 'touchend':
this.isPaint = false;
break;
default:
this.isPaint = false;
break;
}
}
这里需要获取 canvas 在视口中距离左边及顶部的距离,有3种方式:
(1) this.cva.getBoundingClientRect():返回一个对象,包含元素的宽、高及距窗口上下左右距离;
console.log(this.cva.getBoundingClientRect());

(2) 采用 jQuery 方法 $('.painter').offset():同样返回一个对象,但只包含left值和top值;
console.log($('.painter').offset());

(3) 采用js原生方法获取坐标
console.log(this.cva.offsetWidth); // 800
console.log(this.cva.offsetHeight); // 600
console.log(this.cva.offsetLeft); // 90
console.log(this.cva.offsetTop); // 137
注意:原生 js 只有上述4个方法,没有 offsetRight 和 offsetBottom。
大功告成!至此,已经可以在我们的画布上进行类似于铅笔的绘画了~~当然,这是绘图板最最基本的功能,接下去要实现更多的功能,还会用到更多的 Canvas API,需要进行迭代开发啦,有木有很兴奋,嘿嘿;-)

要知下回如何,请继续阅读 开发Canvas绘画应用(三)-对照绘画
✈ Github:paintApp
✎ 参考:
开发Canvas 绘画应用(二):实现绘画的更多相关文章
- 开发Canvas 绘画应用(一):搭好框架
毕业汪今年要毕业啦,毕设做的是三维模型草图检索,年前将算法移植到移动端做了一个小应用(利用nodejs搭的服务),正好也趁此机会可以将前端的 Canvas 好好学一下~~毕设差不多做完了,现将思路和代 ...
- 开发Canvas 绘画应用(四):实现拖拽绘画
在开发Canvas绘画应用(三):实现对照绘画中,我们实现了视图引导的第一部分,这一篇我们来完成第二部分,即将图片直接拖到画布上进行绘画. ✁ 拖放如何实现? [拖放的基本概念]:创建一个绝对定位的元 ...
- 开发Canvas 绘画应用(三):实现对照绘画
需求分析 在我的毕设中,提出了视图引导的概念,由两部分功能组成: (1)可以对照着图片进行绘画,即将图片以半透明的方式呈现在绘图板上,然后用户可以对照着进行绘画: (2)可以直接将简笔画图片直接拖拽到 ...
- cWeb开发框架,基于asp.net的cWeb应用开发平台介绍(二)
cWeb是基于微软的.Net Framework 4框架,数据库是sql server 2008 r2. cWeb开发框架下载,点击这里去下载. cWeb开发框架借鉴三层架构理论分为三层,分别是:cD ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程(十二):OAuth2.0说明
紧接上一篇<Senparc.Weixin.MP SDK 微信公众平台开发教程(十一):高级接口说明>,这里专讲OAuth2.0. 理解OAuth2.0 首先我们通过一张图片来了解一下OAu ...
- iOS开发Swift篇—(二)变量和常量
iOS开发Swift篇—(二)变量和常量 一.语言的性能 (1)根据WWDC的展示 在进行复杂对象排序时Objective-C的性能是Python的2.8倍,Swift的性能是Python的3.9倍 ...
- SNF开发平台WinForm之二-开发-单表表单管理页面-SNF快速开发平台3.3-Spring.Net.Framework
2.1运行效果: 2.2开发实现: 2.2.1 这个开发与第一个开发操作步骤是一致的,不同之处就是在生成完代码之后,留下如下圈红程序,其它删除. 第一个开发地址:开发-单表表格编辑管理页面 http: ...
- 使用Jquery+EasyUI 进行框架项目开发案例讲解之二---用户管理源码分享
使用Jquery+EasyUI 进行框架项目开发案例讲解之二 用户管理源码分享 在上一篇文章<使用Jquery+EasyUI进行框架项目开发案例讲解之一---员工管理源码分享>我们分享 ...
- JAVA+PHP+阿里云组件纯手工实现POP、SMTP、IMAP开发邮件服务器(二)
java开发邮件服务器的接收模块 用java建立socket服务端,监听端口25,实现SMTP协议.即可完成邮件服务器的接收模块. 这里要注意的是,SMTP协议其实可以分为两种.一种是你用手机.PC等 ...
随机推荐
- 学号 20175212童皓桢 《Java程序设计》第8周学习总结
学号 20175212童皓桢 <Java程序设计>第8周学习总结 教材学习内容总结 泛型 class People<E> 其中People是泛型类的名称,E是其中的泛型,也就是 ...
- js设置radio单选框值选中
html页面: <div> <label><input type="radio" name="sex" value="m ...
- 数据结构~Sqlserver索引使用的B树
B树相关概念 在B-树中查找给定关键字的方法是,首先把根结点取来,在根结点所包含的关键字K1,…,Kn查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功:否则,一定可以 ...
- 我的主博客在CSDN,这里只有部分文章,这是地址https://blog.csdn.net/z979451341
我的主博客在CSDN,这里只有部分文章,这是地址https://blog.csdn.net/z979451341
- test--3
<script type="text/javascript">// <![CDATA[$(function () { if (isLogined &&am ...
- numpy数组及处理:效率对比
def Sum(n): #定义一个函数(注意:格式对齐,否则会出错) a=list(range(n)) b=list(range(0,50000*n,5)) c=[] for i in range(l ...
- mysql5.7.20 windows 解压缩版安装
1.下载 文件下载路径:https://dev.mysql.com/downloads/mysql/ 2.配置文件 在解压的文件夹内新建my.ini文件,并加入以下内容: [mysql] # 设置my ...
- win10 如何关掉自带的杀毒软件 window defender
问题描述: win10系统,自带的杀毒软件 window defender 会实时保护电脑对文件进行检测,将认为的病毒文件自动清除, 造成我想下载的MDK5的注册机一直下载不成功,即使从别处拷贝过来, ...
- 掩码图制作----c语言贴图
1.首先你得有一张图,比如这样的: 2.用PS打开他... 3.左边工具栏里(快速选择工具W),选想显示的部分 4.ctrl+c复制一下,新建一张黑底图粘贴上去或者白底图时选中显示区即花瓣右键反向右键 ...
- CentOS7.6配置do.cker和K.B.S
方法一: 节点及功能 主机名 IP Master.etcd.registry K8s-01 10.8.8.31 Node1 K8s-02 10.8.8.32 Node2 K8s-03 10.8.8. ...