HarmonyOS鸿蒙Next中在一个圆形内如何实现根据不同的进度展示水波纹

HarmonyOS鸿蒙Next中在一个圆形内如何实现根据不同的进度展示水波纹,有哪位大佬知道的分享下吗?

3 回复

const COLOR_TRANSPARENT = ‘#00000000’ const COLOR_BACKGROUND_FILL = ‘#7ebede’ const DIAMETER = 200; const RADIUS_IN_PX = vp2px(DIAMETER / 2.0); const BIG_DIAMETER = 220;

@Entry @Component struct Page3 { @State outSetValue: number = 50 @State pathCommands: string = ‘’ @State backGroundColor: string = ‘#00000000’

onPageShow() { this.pathCommands = this.calPathCommands(this.outSetValue); }

calXSquare(y: number) { return RADIUS_IN_PX * RADIUS_IN_PX - (y - RADIUS_IN_PX) * (y - RADIUS_IN_PX); }

calY(k: number) { return (1 - k) * RADIUS_IN_PX * 2; }

formatPathCommands(x1: number, x2: number, y: number, radius: number) { return M${x1} ${y} A${radius} ${radius} 0 ${y > RADIUS_IN_PX ? 0 : 1} 0 ${x2} ${y} + Q${(x1 + 3 * x2) / 4} ${y + 12.5 * (x2 - x1) / radius}, ${(x1 + x2) / 2} ${y} T${x1} ${y} }

calPathCommands(value: number): string { let y = this.calY(value / 100.0) let squareX = this.calXSquare(y) if (squareX >= 0) { let x = Math.sqrt(squareX); let x1 = RADIUS_IN_PX - x; let x2 = RADIUS_IN_PX + x; return this.formatPathCommands(x1, x2, y, RADIUS_IN_PX); } return “”; }

build() { Column() { Column() { Stack() { // 外框圆环 Circle({ width: BIG_DIAMETER, height: BIG_DIAMETER }) .fill(COLOR_TRANSPARENT) .stroke(’#007DFF’) .strokeWidth(5) // 进度显示 Circle({ width: DIAMETER, height: DIAMETER }) .fill(this.backGroundColor) Path() .width(DIAMETER) .height(DIAMETER) .commands(this.pathCommands) .fill(COLOR_BACKGROUND_FILL) // 进度 Text(this.outSetValue.toFixed(0) + “%”) .fontSize(60) }.width(BIG_DIAMETER) .height(BIG_DIAMETER) Row() { Slider({ value: this.outSetValue, min: 0, max: 100, step: 1, style: SliderStyle.OutSet }) .blockColor(’#FFFFFF’) .trackColor(’#182431’) .selectedColor(’#007DFF’) .showSteps(true) .showTips(true) .onChange((value: number, mode: SliderChangeMode) => { this.outSetValue = value if (this.outSetValue == 100) { this.backGroundColor = COLOR_BACKGROUND_FILL this.pathCommands = ‘’; } else { this.backGroundColor = COLOR_TRANSPARENT this.pathCommands = this.calPathCommands(this.outSetValue); } console.log(value = ${value} -> + this.pathCommands); }) Text(this.outSetValue.toFixed(0)).fontSize(16) } }.width(‘100%’) } .height(‘100%’) .justifyContent(FlexAlign.Center) } }

更多关于HarmonyOS鸿蒙Next中在一个圆形内如何实现根据不同的进度展示水波纹的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS NEXT中,要实现圆形水波纹进度效果,可以使用Canvas组件结合自定义绘制。步骤如下:

  1. 创建Canvas组件并设置宽高为圆形直径
  2. 使用Path2D绘制圆形路径作为波纹容器
  3. 通过AnimationController控制进度值变化
  4. 在onDraw回调中:
    • 清除画布
    • 绘制底层圆形背景
    • 根据当前进度值计算波纹高度
    • 使用贝塞尔曲线绘制波纹形状
    • 添加渐变填充增强视觉效果

关键代码示例:

// 波纹动画逻辑
animateTo({ duration: 1000 }, () => {
  this.progress = targetValue
})

在HarmonyOS Next中实现圆形水波纹进度效果,可以通过Canvas绘制结合动画实现。以下是核心实现思路:

  1. 使用Canvas组件绘制基础圆形和水波纹:
Canvas(this.context)
  .width(200)
  .height(200)
  .onReady(() => {
    // 绘制背景圆
    this.context.beginPath();
    this.context.arc(100, 100, 90, 0, 2 * Math.PI);
    this.context.fillStyle = '#F0F0F0';
    this.context.fill();
    
    // 绘制水波纹
    this.drawWave(progressValue);
  })
  1. 水波纹绘制函数(关键代码):
private drawWave(progress: number) {
  const amplitude = 10; // 波纹振幅
  const frequency = 0.02; // 波纹频率
  const centerY = 100 - (180 * progress); // 根据进度调整Y轴位置
  
  this.context.beginPath();
  for (let x = 10; x <= 190; x++) {
    const y = centerY + amplitude * Math.sin(frequency * x);
    this.context.lineTo(x, y);
  }
  
  // 闭合路径形成波纹区域
  this.context.lineTo(190, 200);
  this.context.lineTo(10, 200);
  this.context.closePath();
  this.context.fillStyle = '#1890FF';
  this.context.fill();
}
  1. 结合动画更新进度:
// 使用动画驱动进度变化
animateTo({
  duration: 1000,
  iterations: -1, // 循环动画
}, () => {
  this.progressValue = (this.progressValue + 0.1) % 1;
  this.drawWave(this.progressValue);
})

注意事项:

  • 通过调整amplitude可改变波纹高度
  • frequency控制波纹密度
  • 进度值progress范围应为0-1
  • 建议使用requestAnimationFrame优化动画性能

这种实现方式性能较好,且能灵活控制波纹效果。如需更复杂效果,可考虑叠加多层正弦波。

回到顶部