www.ydisp.cn/oss/202207/13/c3bc709152dbfc0c9f89728e01780ef4ad7541.png"style="visibility:visible;宽度:600px;height:335px;"data-type="inline">了解更多开源请访问:开源基础软件社区https://ost.51cto.com前言最近在学习openHarmony,刚刚学习之前讲过canvas,所以这篇文章分享一个我用openHarmony内置的APIcnavas组件实现的手绘板,这是一个可以根据线条大小动态生成的手绘板到滑动屏幕的速度。当用户触摸屏幕时,会产生线条,速度越快,线条越细。效果显示原理分析1.使用绘图原理之前,需要先了解canvas组件可以参考harmonyOS开发者文档,文档很详细,这里就不介绍了,首先我们要设置canvas上下文对象需要绑定在touch移动事件中,因为我们生成了相应的线路通过触摸。然后属性选择lineCap,属性值一共有三个:butt,round,square。我试过之后发现圆形的效果更好。属性值为butt时,效果属性值为round。属性值为正方形。其实对接效果还不错,就是锯齿太厉害了。虽然API内置了抗锯齿属性,但不知道为什么设置后没有效果。可能粒度太大了,现在这个粒度已经有点卡了,如果你设置的粒度小一点,就更卡了。综上,我还是选择了round,这样会把线的端点以圆形结束,这样效果更圆润。最后取出数组中最后一个A值作为moveTo的坐标,鼠标移动后的点作为lineTo的坐标,就可以通过stroke绘制图像了。画一条直线,通常用到两个方法,moveTo()和lineTo()。moveTo()方法用于将画笔移动到指定点,并将改变后的点作为直线的起点,以及lineTo()为终点。constel=this.$refs.canvas;this.ctx=el.getContext('2d')this.ctx.lineWidth=this.lineWidth/2this.ctx.beginPath()//在线形线帽的两端添加圆圈。this.ctx.lineCap='square'//每次取出数组中的最后一个值作为起点this.ctx.moveTo(this.ArrX[this.ArrX.length-1],this.ArrY[this.ArrY.length-1])this.ctx.lineTo(e.touches[0].localX,e.touches[0].localY)this.ctx.stroke()this.ArrX.push(e.touches[0].localX)this.ArrY.push(e.touches[0].localY)2.线宽如果想通过速度计算线宽,那么需要获取两点之间的时间,通过时间获取速度和距离。当触发touchmove事件时,存储当前时间戳,最后一次触发事件获取的时间-当前触发事件获取的时间可以用来获取两次触发事件之间的事件间隔。这时候我们就得到了两点时间之间的时间。然后计算两点之间的距离(平方和再开根号),通过距离/时间=速度计算两点之间的速度,这样就可以动态生成线的粗细了。//计算线宽constcurrTime=Date.now()if(this.startTime!==0){constduration=currTime-this.startTime//传入倒数第二个和最后一个点,以及持续时间,会返回加速度constv=this.speed(this.ArrX[this.ArrX.length-2],this.ArrY[this.ArrY.length-2],this.ArrX[this.ArrX.length-1],this.ArrY[this.ArrY.length-1],duration)this.lineWidth=this.lineWidth/vif(this.lineWidth>25){this.lineWidth=25}if(this.lineWidth<1){this.lineWidth=1}}this.startTime=currTime完整代码index.js://@ts-nocheckexportdefault{data:{ctx:'',ArrX:[],ArrY:[],//开始时间startTime:0,lineWidth:14},//偏移很多touchstart(e){//清除开始时间this.startTime=0this.ArrX.push(e.touches[0].localX)this.ArrY.push(e.touches[0].localY)},//计算最后两点的速度(x1,y1,x2,y2,s){constx=Math.abs(x1-x2)*Math.abs(x1-x2)consty=Math.abs(y1-y2)*Math.abs(y1-y2)returnMath.sqrt(x+y)/s},touchmove(e){//计算线宽constcurrTime=Date.now()if(this.startTime!==0){constduration=currTime-this.startTime//传入倒数第二个点、最后一个点和持续时间,将返回加速度constv=this.speed(this.ArrX[this.ArrX.length-2],this.ArrY[this.ArrY.length-2],this.ArrX[this.ArrX.length-1],this.ArrY[this.ArrY.length-1],duration)this.lineWidth=this.lineWidth/vif(this.lineWidth>25){this.lineWidth=25}if(this.lineWidth<1){this.lineWidth=1}}this.startTime=currTimeconstel=this.$refs.canvas;this.ctx=el.getContext('2d')this.ctx.lineWidth=this.lineWidth/2this.ctx.beginPath()//将圆形线帽添加到线的每一端this.ctx.lineCap='square'//每次取出数组中的最后一个值作为起点this.ctx.moveTo(this.ArrX[this.ArrX.length-1],this.ArrY[this.ArrY.length-1])this.ctx.lineTo(e.touches[0].localX,e.touches[0].localY)this.ctx.stroke()this.ArrX.push(e.touches[0].localX)this.ArrY.push(e.touches[0].localY)},touchend(e){this.startTime=0}}index.hml:
