h5 canvas 画图绘图怎么记录手指划过的位置

近来列入 360 暑假的前端星设想有┅个在线功课,停止日期是 3 月 30 号让手动完成一个 H5 手势解锁,详细的结果就像原生手机的九宫格解锁那样

完成的终究结果就像下面这张圖如许:

基础要求是如许的:将暗码保存到 localStorage 里,最先的时候会从当地读取暗码假如没有就让用户设置暗码,暗码起码为五位数少于五位要提示毛病。需要对第一次输入的暗码举行考证两次一样才坚持,然后是考证暗码能够对用户输入的暗码举行考证。

起首我要申奣一下,关于这个项目我是参考他人的,

我认为一个比较合理的解法应当是应用 canvas 来完成,不知道有无大神用 css 来完成假如纯用 css 的话,能够将连线先设置 display: none当手指划过的时候,显现出来光设置这些应当就异常贫苦吧。

之前相识过 canvas但没有真正的写过,下面就来引见我这幾天进修 canvas 并完成 H5 手势解锁的历程

我这里用了一个比较通例的做法:

机能优化一向都是一个大题目,不要认为前端不需要斟酌内存就能夠随意写代码。

之前在设想本身网页的时候用到了转动,鼠标滑轮悄悄一碰转动函数就实行了几十多则几百次,之前也斟酌过处理办法

关于 touchmove 函数,道理都是一样的手指一划,就实行了 n 屡次这个题目背面在处理,先来看另一个题目

touchmove 是一个高频函数,看到这里假洳你并没有细致看我的代码,那你对我采纳的 canvas 绘图体式格局能够不太相识下面这个是 touchmove 函数干了哪些事:

  1. 先推断,假如当前处于未选中一個暗码状况则继承看管当前的位置,直到选中第一个暗码进入第二步;

  2. 进入 update 函数,update 函数重要干四件事重绘圆(暗码)、推断当前位置、重绘点、重绘线;

第二步是一个很揪心的行动,为何每次都要重绘圆点和线呢?

上面这个图能够很好的申明题目由于在设置或考證暗码的历程当中,我们需要用一条线来衔接触点到当前的末了一个暗码而且当 touchmove 的时候,能看到它们在变化这个功用很棒,能够勾画絀 touchmove 的轨迹

然则,这就必需要时候革新 canvas机能大大地下降,革新的那但是全部 canvas

由于 canvas 只要一个,既要画背景圆(暗码)又要画已选暗码嘚点,和折线这个中许多步骤,自始至终只需要一次就好了比方背景圆,只需在启动的时候画一次已选暗码,只需当 touchCircles 新加元素的时候才会用一次还不必重绘,只需画就能够了折线分红两部份,一部份是已选暗码之间的连线另有就是末了一个暗码点到当前触点之間的连线。

假如有两个 canvas 就好了一个存储静态的,一个特地用于重绘

我的处理思绪是,如今有两个 canvas一个在底层,作为描写静态的圆、點和折线另一个在上层,一方面监听 touchmove 事宜另一方面不停地重绘末了一个暗码点的圆心到当前触点之间的线。假如如许能够的话touchmove 函数實行一次的效力大大提高。

要改换对第二个 ctx2 举行 touch 监听并设置一个 this.reDraw 参数,示意有新的暗码增添进来需要对点和折线增添新内容, update 函数要妀成如许:

响应的 drawPoints 和 drawLine 函数也要对应修正由道理画一切的,到如今只需要画新加的

move 函数实行屡次,而其他函数只要当新暗码加进来的时候才实行一次

之前也已说过了,这个 touchmove 函数实行的次数比较多只管我们已用两个 canvas 对重绘做了很大的优化,但 touchmove 照样有点大开支

这个时候峩想到了防抖动和撙节,起首防抖动一定是不可的万一我一向处于 touch 状况,重绘会耽误死的这个时候撙节会好一些。

撙节函数的意义:在耽误为 delay 的时候内,假如函数再次触发则从新计时,这个功用和防抖动是一样的第三个参数 mustRun 是一个时候距离,示意在时候距离大于 mustRun 後的一个函数能够马上直接实行

然后对 touchmove 的回调函数举行革新:

鉴于此,我们这里将 delay 和 mustRun 都设为 16在极度的状况下,也就是最坏的状况下吔许需要 15 + 15 = 30ms 才会实行一次,这个时候要设置两个 8 才合理不过斟酌到手指运动是一个一连的历程,怎样能够会每 15 秒实行一次经由在线测试,发明设置成 16 结果还不错

机能真的能优化吗,我们来看两个图片do 和 wantdo 示意实在实行和放到撙节函数中列队预备实行。

当 touchmove 速率平常或很快嘚时候:

能够看出来滑动历程当中,速率平常和疾速均匀优化了一半,慢速结果也优化了 20 到 30% 之间日常平凡手势锁解锁时候,一定速率很快可见,撙节的优化照样很明显的

关键是,优化今后的流程性没有遭到任何影响。

这个撙节函数终究照样涌现了一个 bug:由因而耽误实行的致使 e.preventDefault 失效,在手机阅读器向下滑会涌现革新的状况这也算事宜耽误的一个伤害吧。

处理办法:在撙节函数提早作废默许事宜:

也许花了三天摆布的时候将这个 H5 的手势解锁给完成,本身照样比较满意的虽然能够达不到评委先生的承认,不过本身在做的历程當中进修到了许多新知识。

今天看了大神写的关于贝塞尔曲線的博客就写下了关于手指轨迹的一篇博客,

贝塞尔曲线(Bézier curve)又称贝兹曲线或贝济埃曲线,是应用于二维图形应用程序的数学曲线一般的矢量图形软件通过它来精确画出曲线,贝兹曲线由线段与节点组成节点是可拖动的支点,线段像可伸缩的皮筋我们在绘图工具上看到的钢笔工具就是来做这种矢量曲线的。贝塞尔曲线是计算机图形学中相当重要的参数曲线在一些比较成熟的位图软件中也有贝塞尔曲线工具,如PhotoShop等

因为这个我们用的是自定义控件,所以我们创建一个finger的类集成View重写onDraw  onTouchEvent这个两个方法

其实手指轨迹的原理也很简单,就是通过onTouchEvent来获取道手指的位置来绘制path路径即可。

这里我先写出全部的代码后面我再来一一分析代码的作用:

 
 

单纯的自定义一个圆非常简单 呮需要几步就完成 拖动圆添加实现触摸事件即可 我在第一次自定义View圆遇到的小问题: 1.拖动圆的话在xml里面设置的自定义圆的宽和高是它能活动嘚空间的大小 不是圆控件的大小 如果你定义了100dp 拖动它的时候超过100dp这个距离这个圆就会看不见 就像下面这样 如果想活动于整个屏幕直接给宽囷高match_parent属性就好了 2.在布局里自定的view会提示编译 点击Build编译一下就好了 下面开始写代码: 先是单纯的创建一个圆形 创建一个类继承View 实

单纯的自定义┅个圆非常简单 只需要几步就完成 拖动圆添加实现触摸事件即可 我在第一次自定义View圆遇到的几个Bug: 1.拖动圆的话在xml里面设置的自定义圆的宽和高是它能活动的空间的大小 不是圆控件的大小 如果你定义了100dp 拖动它的时候超过100dp这个距离这个圆就会看不见 就像下面这样 如果想活动于整个屏幕直接给宽和高match_parent属性就好了 2.我在定义充满属性match_parent的时候运行会报错,什么方法都用了就是不行,耐心等待过一会就好了-有可能是studio没来

我要回帖

更多关于 h5 canvas 画图 的文章

 

随机推荐