介绍
一个加载等待组件,提供可自定义的圆形加载动画效果。
链接
https://gitee.com/HW-Commons/ZUtils/blob/master/ui/loading/src/main/ets/components/LoadingView.ets
效果图
下载安装
在每个har/hsp模块中,通过ohpm工具下载安装库:
ohpm install @hzw/zloading
使用方法
@Component
struct Index {
build() {
// LoadingView({
// // 等待弹窗大小
// loadSize: 200,
// // 等待弹窗边距
// loadPadding: 20,
// // 等待弹窗线的宽度
// loadStrokeWidth: 10,
// // 内圆半径
// innerRadius: 0,
// // 外边框圆角
// loadBorderRadius: 20
// })
LoadingView()
}
}
参数说明
参数名 | 类型 | 默认值 | 说明 |
---|---|---|---|
loadSize | number | 200 | 等待弹窗的大小 |
loadPadding | number | 20 | 等待弹窗的内边距 |
loadStrokeWidth | number | 10 | 等待弹窗线条的宽度 |
innerRadius | number | 0 | 内圆半径,为0时默认为外圆半径的1/3 |
loadBorderRadius | number | 20 | 外边框的圆角大小 |
源码
/**
* @author: HHBin
* @date: 2024/12/18
* @desc: 加载等待控件
*/
@Preview
@Component
export struct LoadingView {
/**
* 等待弹窗大小
*/
@Prop loadSize: number = 200
/**
* 等待弹窗边距
*/
@Prop loadPadding: number = 20
/**
* 等待弹窗线的宽度
*/
@Prop loadStrokeWidth: number = 10
/**
* 内圆半径,为 0 时默认为 1/3 圆半径
*/
@Prop innerRadius: number = 0
/**
* 外边框圆角
*/
@Prop loadBorderRadius: number = 20
/**
* 画布
*/
private mCanvas: CanvasRenderingContext2D = new CanvasRenderingContext2D(new RenderingContextSettings(true))
/**
* 线的数量
*/
private mLineNum: number = 10
/**
* 每个线都角度
*/
private mAngle: number = 360 / this.mLineNum
/**
* 等待控件的宽
*/
private mW: number = 0
/**
* 等待控件的高
*/
private mH: number = 0
/**
* 中心坐标的 x 坐标
*/
private mCX: number = 0
/**
* 中心坐标的 y 坐标
*/
private mCY: number = 0
/**
* 中心坐标的 y 坐标
*/
private mRadius: number = 0
private mTime = 0
build() {
Canvas(this.mCanvas)
.onSizeChange((_oldValue: SizeOptions, newValue: SizeOptions) => {
if (typeof (newValue.width) === "number" && typeof (newValue.height) === "number") {
this.mW = newValue.width
this.mH = newValue.height
this.mRadius = this.loadSize / 2;
if (this.innerRadius === 0) {
this.innerRadius = this.mRadius / 3;
}
this.mCX = this.mW / 2;
this.mCY = this.mH / 2;
}
this.mCanvas.lineWidth = this.loadStrokeWidth
})
.backgroundColor(Color.Gray)
.width(this.loadSize)
.height(this.loadSize)
.padding(this.loadPadding)
.borderRadius(this.loadBorderRadius)
.onReady(() => {
this.drawCanvas()
setInterval(() => {
this.drawCanvas()
}, 150)
})
}
private drawCanvas() {
this.mTime = (this.mTime + 1) % 1000
this.mCanvas.clearRect(0, 0, this.mW, this.mH)
let path = new Path2D();
for (let i = 0; i < this.mLineNum; i++) {
const fraction = (Math.abs(i + this.mTime) % this.mLineNum + 1) / this.mLineNum
this.mCanvas.strokeStyle = `rgba(255,255,255,${fraction})`
this.mCanvas.beginPath();
const startX = this.mCX + this.innerRadius * Math.cos(this.angleToPi(this.mAngle * i));
const startY = this.mCY + this.innerRadius * Math.sin(this.angleToPi(this.mAngle * i));
const endX = this.mCX + this.mRadius * Math.cos(this.angleToPi(this.mAngle * i));
const endY = this.mCY + this.mRadius * Math.sin(this.angleToPi(this.mAngle * i));
this.mCanvas.moveTo(startX, startY);
this.mCanvas.lineTo(endX, endY);
this.mCanvas.stroke();
}
path.arc(this.mCX, this.mCY, this.mRadius, 0, 6.28);
}
private angleToPi(angle: number) {
return angle * Math.PI / 180;
}
}