【Harmony】鸿蒙自定义加载等待组件LoadingView

介绍

一个加载等待组件,提供可自定义的圆形加载动画效果。

链接

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()
  }
}

参数说明

参数名类型默认值说明
loadSizenumber200等待弹窗的大小
loadPaddingnumber20等待弹窗的内边距
loadStrokeWidthnumber10等待弹窗线条的宽度
innerRadiusnumber0内圆半径,为0时默认为外圆半径的1/3
loadBorderRadiusnumber20外边框的圆角大小

源码

/**
 * @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;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值