一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种基于H5Canvas实现还原手写笔迹的涂鸦方法与流程

2021-12-07 23:57:00 来源:中国专利 TAG:
一种基于h5 canvas实现还原手写笔迹的涂鸦方法
技术领域
1.本发明公开了一种基于h5 canvas实现还原手写笔迹的涂鸦方 法。


背景技术:

2.随着前端技术的拓展和更新,h5支持了绘图标签canvas。canvas 为web端提供了画板功能,用户可以再web端绘制各种涂鸦。canvas 的出现使得复杂的2d/3d图像显得更加流畅。因此使用canvas技术 也更加普遍。pointer

event事件的出现让h5更加的变得灵活支持的外 接设备也越来越多。pointer

event事件的pointermove事件触发的时候 会获取一连串的点,当点的数量很多的时候就会连成一条曲线。根据 移动的速度不同获取到的点位置信息不同,当移动的块获取点之间的 距离就会相隔很远,移动距离慢的时候获取点之间的相隔就会很近, 根据点的密度可以粗略算出哪些点的半径大,哪些点的半径小,这样 可以粗略的得到类似笔锋效果的涂鸦。


技术实现要素:

3.本发明主要在现有技术基础上发明了一种基于h5 canvas实现 还原手写笔迹的涂鸦方法。
4.本发明解决其技术问题所采用的技术方案包括如下步骤:
5.步骤1、使用两层canvas画布,一层用来绘画,一层用来显示 涂鸦;同时监听绘画层画布的pointerdown事件、pointermove事件 和pointerup事件。
6.步骤2、当画笔按下时,触发pointerdown事件,然后初始化 canvas画笔的基本属性,包括线宽、颜色和样式等信息。
7.步骤3、根据触发pointerdown事件返回的参数event,判断是 否为手写笔设备,如果是手写笔设备则记录当前压感系数p,然后根 据压感系数p的平方和canvas画笔线宽相乘得到当前点a1的半径 r1,即r1=math.pow(p,2)*linewidth,其中math.pow()表示平方 函数,linewidth表示canvas画笔线宽;如果不是,则初始化压感 系数为0,然后取当前canvas画笔线宽的一半得到此时的半径,即 r1=linewidth*0.5;然后将当前点a1的信息保存在涂鸦笔迹数组 中。
8.步骤4、当画笔移动时触发pointermove事件,根据pointermove 事件触发时获取到点的位置信息和压感系数p(压感系数处理方式和 步骤3处理方式相同),然后获取到移动后当前第一个点b1与步骤 3记录下的点a1进行比较,计算出两点之间的距离位置坐标的差值 (dx,dy);其中dx是两个点之间横坐标的差值,dy是两个点之间 纵坐标的差值;再根据当前差值(dx,dy)的平方根curdis乘以滑 动固定系数0.02得到当前curvel(即curvel= math.hypot(dx,dy)*0.02);
9.curvel用来判断当前此处的笔锋是细还是加粗,当curvel大于 设定阈值时,当前此处的笔锋为加粗,否则当前此处的笔锋为细;
10.根据差值(dx,dy)判断是否符合贝塞尔曲线最小移动的距离(即 dx>4和dy>4。ps:
4是符合贝塞尔曲线的最小移动像素),然后再根 据两点之间差值(dx,dy)的平方根curdis(即curdis= math.hypot(dx,dy))、点a1的半径r1、curvel和点a2的压感系数 p来计算当前点a2的半径r2,记录当前a2的信息,将当前点a2的 信息保存在涂鸦笔迹数组中,然后初始化贝塞尔曲线函数类。
11.r2=linewidth*math.exp(math.log(1.5*2)*(

curvel*0.6 p*(1

0.6))))
12.步骤5、然后根据pointermove事件获取得到一连串点,取第二 个点a3与步骤4记录的点a2进行比较,根据步骤4获取的点a2半 径r2的方法,获取当前点a3的半径r3;然后记录当前点a3并且添 加到贝塞尔曲线的函数类中。用相同的方法计算出剩余一连串点中所 有点的半径,并且添加到贝塞尔曲线函数类中,且把每个点的信息保 存在涂鸦笔迹数组中。
13.步骤6、根据涂鸦笔迹数组中相邻两点之间的距离dis1,从贝 塞尔曲线函数类中取出满足贝塞尔曲线函数的点的数组 gradualpoints。
14.步骤7、对当前gradualpoints数组,取任意相邻两点之间的距 离dis2,根据点a1的半径r1、点a2的半径r2和当前的涂鸦线宽的 一半,取3个变量中的最小值作为当前涂鸦填点的最小半径 minradius.
15.若当前的涂鸦线宽linewidth小于6像素,则通过1加上当前相 邻点之间的距离dis2除以minradius的商计算出需要填点的个数 steps:即steps=1 dis2/minradius;
16.若当前线宽linewidth大于6像素,则根据当前相邻点之间的距 离dis2除以minradius的商再乘以2计算出需要填点的个数steps: 即steps=(dis2/minradius)*2;
17.根据当前steps计算点a1到点a2的x轴、y轴和半径分别需要 变化的值deltax、deltay和deltaw;
18.deltax=(a1.x

a2.x)/steps;
19.deltay=a1.y

a2.y)/steps;
20.deltaw=(a1.r

a2.r)/steps;
21.然后每循环一遍都调用cavas api进行涂鸦绘图,直至循环steps 遍。
22.步骤8、画笔抬起的时候处理画笔末尾的涂鸦,当前画笔抬起时 触发pointerup事件获取当前点的位置信息(x,y)和压感系数p, 把当前点和上一步的最后一个点进行对比,然后根据步骤4的计算方 法得到当前点的位置信息(x,y)和半径r,然后结束当前贝塞尔曲 线的填点过程。
23.根据步骤6获取满足贝塞尔曲线的集合,得到一个新的数组 arr1,根据步骤7对数组arr1中的点进行绘制涂鸦;把数组arr1和 步骤6得到的数组gradualpoints进行合并得到新的数组savearr。
24.所述的数组arr1具体根据当前点的位置信息和上一个点(从涂 鸦笔迹数组中取到的)这个两个点计算出距离dis3,然后再从贝塞 尔曲线函数类中,获取符合贝塞尔曲线的点的数组即为arr1。步骤9、 基于得到的数组savearr,根据步骤7方法生成符合相应的svg路径 集合,并且使用fabric.js的path方法在渲染层画布上绘制出相应 涂鸦,并且清空绘画层画布的涂鸦。
25.进一步是,所述的距离dis1、距离dis2、距离dis3均是预设的 值。
26.本发明有益效果如下:
27.本发明使用h5中的canvas标签自带的api实现涂鸦效果,贝塞 尔曲线的使用让涂鸦的线段变的更加平滑。使用h5的pointer

event 事件支持鼠标、触摸和写字笔事件,并且可以获取到写字笔的压感系 数。同时使用第三方框架fabric.js来实现canvas的性能问题。
28.使用两层canvas画布能够更好的优化canvas的性能。
具体实施方式
29.下面结合实施例对本发明作进一步说明。
30.一种基于h5 canvas实现还原手写笔迹的涂鸦方法,具体包括 如下步骤:
31.步骤1、使用两层canvas画布,一层用来绘画,一层用来显示 涂鸦;同时监听绘画层画布的pointerdown事件、pointermove事件 和pointerup事件。
32.步骤2、当画笔按下时,触发pointerdown事件,然后初始化 canvas画笔的基本属性,包括线宽、颜色和样式等信息。
33.步骤3、根据触发pointerdown事件返回的参数event,判断是 否为手写笔设备,如果是手写笔设备则记录当前压感系数p,然后根 据压感系数p的平方和canvas画笔线宽相乘得到当前点a1的半径 r1,即r1=math.pow(p,2)*linewidth,其中math.pow()表示平方 函数,linewidth表示canvas画笔线宽;如果不是,则初始化压感 系数为0,然后取当前canvas画笔线宽的一半得到此时的半径,即 r1=linewidth*0.5;然后将当前点a1的信息保存在涂鸦笔迹数组 中。
34.步骤4、当画笔移动时触发pointermove事件,根据pointermove 事件触发时获取到点的位置信息和压感系数p(压感系数处理方式和 步骤3处理方式相同),然后获取到移动后当前第一个点b1与步骤 3记录下的点a1进行比较,计算出两点之间的距离位置坐标的差值 (dx,dy);其中dx是两个点之间横坐标的差值,dy是两个点之间 纵坐标的差值;再根据当前差值(dx,dy)的平方根curdis乘以滑 动固定系数0.02得到当前curvel(即curvel= math.hypot(dx,dy)*0.02);
35.curvel用来判断当前此处的笔锋是细还是加粗,当curvel大于 设定阈值时,当前此处的笔锋为加粗,否则当前此处的笔锋为细;
36.根据差值(dx,dy)判断是否符合贝塞尔曲线最小移动的距离(即 dx>4和dy>4。ps:4是符合贝塞尔曲线的最小移动像素),然后再根 据两点之间差值(dx,dy)的平方根curdis(即curdis= math.hypot(dx,dy))、点a1的半径r1、curvel和点a2的压感系数 p来计算当前点a2的半径r2,记录当前a2的信息,将当前点a2的 信息保存在涂鸦笔迹数组中,然后初始化贝塞尔曲线函数类。
37.r2=linewidth*math.exp(math.log(1.5*2)*(

curvel*0.6 p*(1

0.6))))
38.步骤5、然后根据pointermove事件获取得到一连串点,取第二 个点a3与步骤4记录的点a2进行比较,根据步骤4获取的点a2半 径r2的方法,获取当前点a3的半径r3;然后记录当前点a3并且添 加到贝塞尔曲线的函数类中。用相同的方法计算出剩余一连串点中所 有点的半径,并且添加到贝塞尔曲线函数类中,且把每个点的信息保 存在涂鸦笔迹数组中。
39.步骤6、根据涂鸦笔迹数组中相邻两点之间的距离dis1,从贝 塞尔曲线函数类中
取出满足贝塞尔曲线函数的点的数组 gradualpoints。
40.步骤7、对当前gradualpoints数组,取任意相邻两点之间的距 离长度dis2,根据点a1的半径r1、点a2的半径r2和当前的涂鸦线 宽的一半,取3个变量中的最小值作为当前涂鸦填点的最小半径 minradius.
41.若当前的涂鸦线宽linewidth小于6像素,则通过1加上当前相 邻点之间的距离dis2除以minradius的商计算出需要填点的个数 steps:即steps=1 dis2/minradius;
42.若当前线宽linewidth大于6像素,则根据当前相邻点之间的距 离dis2除以minradius的商再乘以2计算出需要填点的个数steps: 即steps=(dis2/minradius)*2;
43.根据当前steps计算点a1到点a2的x轴、y轴和半径分别需要 变化的值deltax、deltay和deltaw;
44.deltax=(a1.x

a2.x)/steps;
45.deltay=a1.y

a2.y)/steps;
46.deltaw=(a1.r

a2.r)/steps;
47.然后每循环一遍都调用cavas api进行涂鸦绘图,直至循环steps 遍。
48.步骤8、画笔抬起的时候处理画笔末尾的涂鸦,当前画笔抬起时 触发pointerup事件获取当前点的位置信息(x,y)和压感系数p, 把当前点和上一步的最后一个点进行对比,然后根据步骤4的计算方 法得到当前点的位置信息(x,y)和半径r,然后结束当前贝塞尔曲 线的填点过程。
49.根据步骤6获取满足贝塞尔曲线的集合,得到一个新的数组 arr1,根据步骤7对数组arr1中的点进行绘制涂鸦;把数组arr1和 步骤6得到的数组gradualpoints进行合并得到新的数组savearr。
50.所述的数组arr1具体根据当前点的位置信息和上一个点(从涂 鸦笔迹数组中取到的)这个两个点计算出dis3,然后再从贝塞尔曲 线函数类中,获取符合贝塞尔曲线的点的数组即为arr1。
51.步骤9、基于得到的数组savearr,根据步骤7方法生成符合相应 的svg路径集合,并且使用fabric.js的path方法在渲染层画布上 绘制出相应涂鸦,并且清空绘画层画布的涂鸦。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献