HarmonyOS - 基于ArkUI(JS)实现自定义circle进度条 原创 精华

中软国际鸿蒙生态
发布于 2022-9-5 11:22
浏览
3收藏

作者:张前霞

前言

最近在FA项目开发中,遇到类似这样的圆形进度条,参考开发文档利用canvas封装成了一个组件,这是一个基于JS扩展的类Web开发范式组件中的基础组件 。

组件介绍

circle进度条组件在开发中经常用到,形式多种多样,参考canvas文档做了简单的一种,支持各种属性调整。有需要可以参考看看。

HarmonyOS - 基于ArkUI(JS)实现自定义circle进度条-鸿蒙开发者社区

HarmonyOS - 基于ArkUI(JS)实现自定义circle进度条-鸿蒙开发者社区

代码演示

  • 默认普通展示
<circularBar  percent = '80' ></circularBar>
  • 显示百分比文字
<circularBar  percent = '60' istext = 'true'></circularBar>
  • 自定义宽度
<circularBar  percent = '60'  bg-width = '20' f-width = '20'></circularBar>
  • 自定义颜色
<circularBar  percent = '60' color-c = '#ff6600'></circularBar>
  • 自定义渐变颜色
<circularBar  percent = '60' color-num = '2' start-c = '#f463b2' end-c = '#376af9'></circularBar>
  • 自定义背景颜色
<circularBar  percent = '60' bg-color = '#6a6a6a'></circularBar>
  • 自定义绘制方向
<circularBar  percent = '60' direction = 'true'></circularBar>

注意

父子组件属性使用:camelCase (驼峰命名法) 的 prop 名,在外部父组件传递参数时需要使用 kebab-case (短横线分隔命名) 形式,即当属性compProp在父组件引用时需要转换为comp-prop。

API

props

参数 说明 类型 默认值
percent 进度条百分比 Number 50
colorNum 颜色值,1:纯色 2: 渐变色 String -
bgWidth 背景圈的宽度 Number 10
fWidth 动态圈的宽度 Number 10
istext 显示百分比文字 Boolean false
direction 绘制方向,顺时针false/逆时针true Boolean false
bgColor 背景圈颜色 String ‘#cccccc’

部分代码展示

1. html部分

<div class="container">
    <div style="margin-left: 10%;">
        <canvas  ref="canvasbox" style="width: 100px; height: 100px;">
        </canvas>
    </div>
</div>

2. js部分

相关api参考

名称 类型 默认值 描述
lineCap string ‘butt’ 指定线端点的样式,可选值为:- ‘butt’:线端点以方形结束。- ‘round’:线端点以圆形结束。- ‘square’:线端点以方形结束,该样式下会增加一个长度和线段厚度相同,宽度是线段厚度一半的矩形。
strokeStyle <color> | CanvasGradient | CanvasPattern - 设置描边的颜色。- 类型为<color>时,表示设置描边使用的颜色。- 类型为CanvasGradient时,表示渐变对象,使用createLinearGradient方法创建。- 类型为CanvasPattern时,使用createPattern方法创建。
font string ‘normal normal 14px sans-serif’ 设置文本绘制中的字体样式。语法:ctx.font=‘font-size font-family’- font-size(可选),指定字号和行高,单位只支持px。- font-family(可选),指定字体系列。语法:ctx.font=‘font-style font-weight font-size font-family’- font-style(可选),用于指定字体样式,支持如下几种样式:‘normal’,talic。- font-weight(可选),用于指定字体的粗细,支持如下几种类型:‘normal’, ‘bold’, ‘bolder’, ‘lighter’, 100, 200, 300, 400, 500, 600, 700, 800, 900。- font-size(可选),指定字号和行高,单位只支持px。- font-family(可选),指定字体系列,支持如下几种类型:‘sans-serif’, ‘serif’, ‘monospace’。
  • 封装组件在onshow()周期内绘制显示不出动画图像,修改为onpageshow()绘制成功,延迟200毫秒画布绘制要在页面展示后才能绘制
//初始绘制
onPageShow(){
    setTimeout(()=>{
        const  darw_el = this.$refs.canvasbox;
        console.info(darw_el)
        //颜色取值不支持#ccc #f60 十六进制颜色 不支持缩写
       this.circleFun(darw_el,this.colorNum,this.percent,this.bgWidth,this.fWidth,this.bgColor,this.textColor,this.istext,this.direction,this.startC,this.endC,this.colorC)
    },200)
},
    
  • 获取canvas绘制图像的宽高值,无法直接获取,需使用getBoundingClientRect()方法 ;这里绘制的中心点,以画布的中点为中心
//定义变量
var rect = draw_item.getBoundingClientRect();
var context = draw_item.getContext('2d');
var center_x = (rect.width)/2;
var center_y = (rect.height)/2;
var rad = (Math.PI *2) /100;
var speed = 0;
  • 绘制圆圈的半径主要以画布的宽度和线圈宽度有关,这里没有把宽度作为props属性值传参进来,使用修改可直接修改画布大小,半径为画布宽度一半减去线圈宽度,结尾形状取值参考
// 绘制后面的圈圈
function  backCircle(){
    context.save()
    context.beginPath()
    context.lineWidth = lineWidth_b // 设置线宽
    var radius = center_x - context.lineWidth //设置半径
    context.lineCap = 'round' //结尾形状
    context.strokeStyle = color_b //线条颜色
    context.arc(center_x, center_y, radius, 0, Math.PI * 2, false)
    context.stroke()
    context.closePath()
    context.restore()
}
  • 进度条填充颜色可自定义选择,colornums取值1为纯色对应传Color_C的颜色值,colornums取值为2为渐变色需传入开始颜色start_C和结束颜色end_C两个颜色值
//绘制前面的圈圈
function  foceCircle(n){
    context.save()
  	//context.strokeStyle = color_f //决定圆环颜色
 	context.lineWidth = lineWidth_f;//前面动态圈宽度
 	context.lineCap = 'round';//结尾形状
 	var radius = center_x - context.lineWidth;//半径
 	context.beginPath()
 	if (colornums == 1) {
		context.strokeStyle = Color_C
 	}
 	if (colornums == 2) {
        //创建渐变对象,渐变开始点和渐变结束点
		let g = context.createLinearGradient(0, 90, 90, 0); 
    	g.addColorStop(0, start_C); //添加颜色点
    	g.addColorStop(1, end_C); //添加颜色点
    	context.strokeStyle = g; //使用渐变对象作为圆环的颜色
 	}
 	//用于绘制圆弧context.arc(x坐标,y坐标,半径,起始角度,终止角度,顺时针/逆时针)
 	//context.arc(center_x,center_y,radius, -Math.PI / 4,-Math.PI / 4 + n * rad,direct )
 	context.arc(center_x,center_y,radius, Math.PI / 20, n*rad, direct )
 	context.stroke()
 	context.closePath()
 	context.restore()
}
  • 文字绘制相关api参考,组件百分比文字显示作为可选项,需要显示时传入istext字段即可。
//绘制文字
function text(n) {
    context.save();
    context.fillStyle = color_f; //文字颜色
    var font_size = 20 ;//字体大小
    context.font = font_size + 'px Helvetica' //字体大小和文字形状
    var text_width = context.measureText(n.toFixed(0) + '%').width;//文字宽度
    context.fillText(n.toFixed(0) + '%', center_x - text_width / 2, center_y + font_size / 2)
    context.restore()
}

  • 在最后执行动画这块做了一个文字百分比的动态增加,这块有一点点的小问题文字动态增加过程中会出现绘制闪动的问题,目前尚未解决,但是不影响正常使用。后续会逐步更新解决。
//执行动画
(function drawFrame() {
	if (speed <= percent) {
		requestAnimationFrame(drawFrame)
    } else {
        return false
    }
    context.clearRect(0, 0, rect.width, rect.height)
    //context.globalCompositeOperation = "copy"
    backCircle();
    //控制百分比文字显示、隐藏
	if(textshow){
		text(speed);
	}
	foceCircle(speed);
	if (speed >= percent) {
		speed ++
	} else {
		speed += 1
	}
})()

总结

此自定义组件运用了canvas绘制,使用和练习中参考官方api,也结合了组件通信,父子组件直接的传值。

缺点是不支持拖动事件,在事件这部分没有做添加,后续在更新中也欢迎其他朋友多多指点。

更多原创内容请关注:中软国际 HarmonyOS 技术团队

入门到精通、技巧到案例,系统化分享HarmonyOS开发技术,欢迎投稿和订阅,让我们一起携手前行共建鸿蒙生态。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
已于2022-9-5 14:47:35修改
6
收藏 3
回复
举报
7条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

进度条的图片是不是没上传成功?

回复
2022-9-5 14:14:46
中软国际鸿蒙生态
中软国际鸿蒙生态 回复了 红叶亦知秋
进度条的图片是不是没上传成功?

漏了,感谢提醒,已补上

回复
2022-9-5 14:48:01
红叶亦知秋
红叶亦知秋 回复了 中软国际鸿蒙生态
漏了,感谢提醒,已补上

ok,可以看到了,感谢修改。

回复
2022-9-5 15:12:30
有故事的王同学
有故事的王同学

api的演示很详细

回复
2022-9-7 10:46:30
FlashinMiami
FlashinMiami

能自己设置的东西总是最好的

回复
2022-9-8 18:14:43
渴望学习的阿诺德
渴望学习的阿诺德

进度条组件的现状和缺点都讲的很清楚,希望后续能添加拖动事件吧。

回复
2022-9-9 10:34:14
wx629ad2fec697a
wx629ad2fec697a

求源码 蟹蟹

回复
2022-10-3 21:31:26
回复
    相关推荐