当前位置: 首页 > 科技观察

HarmonyOS自定义组件可拖动圆形进度条

时间:2023-03-12 08:14:17 科技观察

更多内容请访问:https://harmonyos.51cto.com,与华为官方共同打造的鸿蒙技术社区在项目开发中,我们经常会用到自定义组件。下面分享下HarmonyOS中的JS如何使用canvas为自定义组件实现一个可拖拽的圆形进度条。效果演示实现思路官方文档:JSAPI参考-HarmonyOS应用开发思路参考:拖放圆形进度条组件(支持移动端))这里官方文档没有使用通过element导入到主页的方式;以上流程采用发布一个bug:第一次渲染不显示canvas;解决方案:在页面生命周期onShow中,通过js让画布绘制一次;onShow(){//Tododrawing}1.工程结构2.DragAcr初始化定义构造函数,声明画圆的参数;exportdefaultclassDragAcr{constructor(param){this.initParam(param)this.draw(this.value)}initParam(param){const{el,startAngle=0,endAngle=2,width=252,innerColor="red",outColor="#08000000",innerLineWidth=1,outLineWidth=24,counterclockwise=false,slider=8,color=["#ffffff","#0F75F3","#54C8A5","#FEDB00","re??d"],sliderColor="#ffffff",sliderBorderColor="blue",value=0,change=(v)=>{console.log(v)},textShow=true,}=param;这个。el=el;this.width=width;this.height=width;this.center=this.width/2this.outLineWidth=outLineWidth;this.radius=this.width/2-this.outLineWidth/2;//this.ctx=el.getContext("2d");this.ctx=this.el.getContext('2d',{antialias:true});this.startAngle=startAngle;this.endAngle=endAngle;this.innerColor=innerColor;this.outColor=outColor;this.innerLineWidth=innerLineWidth;this.counterclockwise=逆时针方向;this.slider=slider;this.color=color;this.sliderColor=sliderColor;this.sliderBorderColor=sliderBorderColor;this.value=value;this.textShow=textShow;this.change=change;this.isDown=false;}3.DragAcr绘制canvas的API参考:canvas组件-绘画组件根据当前进度分段式的绘图需要的各个小控件;//绘图draw(value){console.log(TAG+';drawvalue:'+value);if(value==undefined){value=this.value;}else{this.value=value;}this.ctx.clearRect(0,0,this.width,this.width);this.ctx.save();letstartDeg=this.counterclockwise?Math.PI*(2-this.startAngle):Math.PI*this.startAngleletendDeg=this.counterclockwise?Math.PI*(2-this.endAngle):Math.PI*this.endAngle//绘制背景圆this.ctx.beginPath();this.ctx.arc(this.center,this.center,this.radius,startDeg,endDeg,this.counterclockwise);this.ctx.strokeStyle=this.outColor;this.ctx.lineCap="round";this.ctx.lineWidth=this.outLineWidth;this.ctx.stroke();letDeg=this.valToDeg(value)this.drawOne(startDeg,value);if(value>25){//绘制变量弧this.drawTwo(value);}if(value>50){//绘制变量弧this.drawThree(value);}if(value>75){this.drawFour(value)}//绘制滑块barthis.P=this.DegToXY(Deg)this.ctx.beginPath();this.ctx.moveTo(this.center,this.center,);this.ctx.arc(this.P.x,this.P.y,this.outLineWidth/2,0,Math.PI*2,false);//绘制滑块内部this.ctx.fillStyle=this.sliderBorderColor;this.ctx.fill();this.ctx.beginPath();this.ctx.moveTo(this.center,this.center);this.ctx.arc(this.P.x,this.P.y,this.slider,0,Math.PI*2,false);//绘制滑块this.ctx.fillStyle=this.sliderColor;this.ctx.fill();//文本if(this.textShow){this.ctx.font='60pxHarmonyHeiTi,HarmonyHeiTi-Medium';this.ctx.fillStyle="#000000";this.ctx.textAlign="center"this.ctx.textBaseline="middle";this.ctx.fillText(this.value+"",this.center,this.center);}//this.drawLine();}4.DragAcr手势监听手势按下,手势移动,手势的事件处理引发OnMouseMove(evt){if(!this.isDown)return;letevpoint={};evpoint.x=this.getx(evt);evpoint.y=this.gety(evt);letpoint=this.spotchangeXY(evpoint);letdeg=this.XYToDeg(point.x,point.y);//console.log(TAG+';OnMouseMovedegXYToDeg...'+deg);deg=this.counterclockwise?deg:Math.PI*2-deg;//console.log(TAG+';OnMouseMovedeg...'+deg);letval=(deg/Math.PI-this.startAngle)/(this.endAngle-this.startAngle)*100val=Math.round(val)//console.log(TAG+';OnMouseMoveval:'+val);if(val<0)val=100+val;if(val<=0)val=0;if(val>100){if(this.value>75){val=100;}else{val=val-100;}}if(val>75){if(this.value<25){val=0;}}//console.log(TAG+';OnMouseMoveval2:'+val);if(Math.abs(val-this.value)>10)return;//console.log(TAG+';OnMouseMoveval:'+val);this.animate=requestAnimationFrame(this.draw.bind(this,val));if(this.value!=Math.round(val)){this.value=Math.round(val);this.change(this.value)}//console.log(TAG+';OnMouseMoveend...');}OnMouseDown(evt){letrange=10;letX=this.getx(evt);letY=this.gety(evt);letP=this.PletminX=P.x-this.slider-range;letmaxX=P.x+this.slider+range;letminY=P.y-this.slider-range;letmaxY=P.y+this.slider+range;if(minX

索引。jsFileimportDragAcr2from'./dragAcr2.js'exportdefault{dragAcr2:undefineddata:{//事件值reverb2:30,}onShow(){//先绘制this.initDragAcr2();},//触摸事件canvasTouchStart(msg){//console.log('dragAcrcanvasTouchStartmsg:'+msg);this.dragAcr2.OnMouseDown(msg);},canvasTouchMove(msg){//console.log('dragAcrOnMouseMovemsg:'+msg);this.dragAcr2.OnMouseMove(msg);},canvasTouchEnd(msg){//console.log('dragAcrcanvasTouchEndmsg:'+msg);this.dragAcr2.OnMouseUp(msg);},initDragAcr2(){constel=this.$refs.canvas2;if(this.dragAcr2==undefined){this.dragAcr2=newDragAcr2({el:el,value:this.reverb2,change:(v)=>{console.log(`value:${v}`)}})}}}总结1.目前API6及以下手机在绘制canvas时屏幕会闪烁(API7远程模式没有这种现象);2.不管是哪种语言,思路大致相同,画图、手势、事件分发等。更多内容请访问:与华为官方共建的鸿蒙技术社区https://harmonyos.51cto.com