HarmonyOS Next 刻度盘

最近在学习鸿蒙开发,已经学到画图这部分,刚好以前的项目也有这个功能,就写了个demo。 上效果图:

代码也简单,可能有些许不够完美,请见谅。能用的上伙伴拿去改改用。

kotlin 复制代码
@Entry
@Component
export struct CirleProgressPage {

  private settings:RenderingContextSettings = new RenderingContextSettings()
  private context:CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings)

  @Builder setupCirleView(){
    Canvas(this.context)
      .width('90%')
      .height('90%')
      .backgroundColor(Color.Pink)
      .onReady(()=>{

        const  baseRadians:number = 90;
        this.context.beginPath()
        this.context.arc(ResManager.getScreenWidth() / 2,170,baseRadians, this.degreesToRadians(270), this.degreesToRadians(210),false);//逆时针
        this.context.lineWidth = 15
        this.context.strokeStyle = Color.Gray
        this.context.lineCap = 'round'
        this.context.stroke()

        this.context.beginPath()
        this.context.arc(ResManager.getScreenWidth() / 2,ResManager.getScreenHeight() / 2,baseRadians, this.degreesToRadians(90), this.degreesToRadians(360),true);
        this.context.lineWidth = 5
        this.context.strokeStyle = Color.Gray
        this.context.lineCap = 'round'
        this.context.stroke()

        const count = 50;
        const start1 = 360;//开始
        const offset = (5 * 60)/49;
        const radius = baseRadians + 10;
        const centerx = ResManager.getScreenWidth() / 2;
        const centery = 170;


        for (let i = 0; i < count; i++) {
          const angle = offset * i + start1;

          let start:[number,number] = this.getPointWithRadius(radius,centerx,centery,this.degreesToRadians(angle));
          const end:[number,number] = this.getPointWithRadius(radius + 5,centerx,centery,this.degreesToRadians(angle));

          this.context.beginPath();
          if (i % 5 == 0 || i === count - 1){
            this.context.lineWidth = 3;
          }else{
            start = this.getPointWithRadius(radius + 2,centerx,centery,this.degreesToRadians(angle));
            this.context.lineWidth = 2;
          }

          if (i === 0) {
            this.context.strokeStyle = Color.Red
          }else{
            this.context.strokeStyle = Color.Blue
          }

          this.context.moveTo(start[0],start[1])
          this.context.lineTo(end[0],end[1])
          this.context.stroke()

        }

        for (let i = 0; i < count; i++) {
          if (i % 10 == 0 || i === count - 1){
            const angle = offset * i + start1;
            this.context.beginPath();
            this.context.strokeStyle = Color.Green
            let font_start:[number,number] = this.getPointWithRadius(radius + 15,centerx,centery,this.degreesToRadians(angle));

            this.context.font = '35px sans-serif'
            if (i === count - 1) {
              i += 1;
            }
            this.context.fillText(i.toString(),font_start[0] - 5,font_start[1] + 3,30)
            this.context.stroke()

          }


        }



      })

  }


   /**
    * 单位:弧度
    * @param radius
    * @param center_x
    * @param center_y
    * @param angle
    * @returns
    */
  private getPointWithRadius(radius:number,center_x:number,center_y:number,angle:number):[number,number]{
    const x = radius * Math.cos(Math.PI * 2 + Math.PI / 2 - angle)
    const y = radius * Math.sin(Math.PI * 2 + Math.PI / 2 - angle)
    return [center_x + x,center_y - y]
  }

  // 角度 → 弧度
  private  degreesToRadians(degrees: number): number {
    return degrees * Math.PI / 180;
 }

  build() {
    Column() {
      this.setupCirleView()
    }
    .height('100%')
    .width('100%')
  }
}
```
```
相关推荐
狗哥哥8 分钟前
Vue 3 动态菜单渲染优化实战:从白屏到“零延迟”体验
前端·vue.js
青青很轻_10 分钟前
Vue自定义拖拽指令架构解析:从零到一实现元素自由拖拽
前端·javascript·vue.js
树下水月17 分钟前
纯HTML 调用摄像头 获取拍照后的图片的base64
前端·javascript·html
蜗牛攻城狮21 分钟前
Vue 中 `scoped` 样式的实现原理详解
前端·javascript·vue.js
豆苗学前端26 分钟前
前端工程化终极指南(Webpack + Gulp + Vite + 实战项目)
前端·javascript
比老马还六27 分钟前
Bipes项目二次开发/海龟编程(六)
前端·javascript
梨子同志27 分钟前
Node.js 文件系统 fs
前端
码农胖大海28 分钟前
微前端架构(二):封装与实现
前端
瘦的可以下饭了29 分钟前
2 数组 递归 复杂度 字符串
前端·javascript
Kellen29 分钟前
ReactDOM.preload
前端·react.js