HarmonyOS 如何实现音频声浪动画

HarmonyOS 如何实现音频声浪动画

HarmonyOS
2024-08-29 15:45:06
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
zbw_apple

对于您展示的场景,我们总结出以下需求:

1、能够显示特效动画

2、动画可以暂停,自动重复

以上需求,推荐使用三方库gif-drawable或lottie来绘制音频动画。

gif-drawable中心仓地址:

https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Fgif-drawable

gif-drawable使用教程:

https://www.cnblogs.com/openharmony/p/16809257.html

lottie中心仓地址:

https://ohpm.openharmony.cn/#/cn/detail/@ohos%2Flottie

开发者您可以让公司内部视觉设计提供该音效gif或json属性动画文件,然后使用对应的三方库进行渲染。

可以参考demo:

const CANVAS_POS_X1: number = 0; 
const CANVAS_POS_Y1: number = 0; 
const CANVAS_POS_X2: number = 119; 
const CANVAS_POS_Y2: number = 18; 
const START_POS_X: number = 117; 
const OFFSET_X: number = 4.5; 
const RECT_WIDTH: number = 1.5; 
const TWO: number = 2; 
 
@Entry 
@Component 
struct Index { 
 @State message: string = 'Hello World'; 
 @State volumeList: number[] = new Array(27).fill(0); 
 canvasTimer: number = -1; 
 renderingContextSettings: RenderingContextSettings = new RenderingContextSettings(true); 
 canvasRenderingContext2D: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingContextSettings); 
 
 build() { 
  Row() { 
   Canvas(this.canvasRenderingContext2D) 
    .width(CANVAS_POS_X2) 
    .height(18) 
    .backgroundColor(Color.White) 
    .onReady(() => { 
     this.canvasRenderingContext2D.strokeStyle = 
      getContext().resourceManager.getColorSync($r('sys.color.ohos_id_color_text_primary_contrary')); 
     this.canvasRenderingContext2D.lineWidth = RECT_WIDTH; 
     this.canvasRenderingContext2D.lineCap = 'round'; 
     this.refreshVolumeList(); 
    }) 
 
  } 
  .backgroundColor('#4d5e55') 
  .justifyContent(FlexAlign.Center) 
  .alignItems(VerticalAlign.Center) 
  .width('100%') 
  .height(80) 
 } 
 
 refreshVolumeList() { 
  this.canvasTimer = setInterval(() => { 
   this.volumeList.shift(); 
   this.volumeList.push(8  + 10 * Math.random()); 
   this.draw(); 
  }, 70); 
 } 
 
 draw() { 
  this.canvasRenderingContext2D.clearRect(CANVAS_POS_X1, CANVAS_POS_Y1, CANVAS_POS_X2, CANVAS_POS_Y2); 
  for (let index = 0; index < this.volumeList.length; index++) { 
   const element = this.volumeList[index]; 
   if(element === 0) {      continue;    } 
   const posX = START_POS_X - (OFFSET_X * index); 
   const posY = (18 - element) / TWO; 
   this.canvasRenderingContext2D.beginPath(); 
   this.canvasRenderingContext2D.moveTo(posX, posY); 
   this.canvasRenderingContext2D.lineTo(posX, posY + element); 
   this.canvasRenderingContext2D.stroke(); 
  } 
 } 
 
 aboutToAppear() { 
  clearInterval(this.canvasTimer) 
 } 
}

下面是我们通过Canvas实现波浪线效果,开发者您可以在此demo基础上修改波浪线传递方式,并通过多次覆盖绘制实现音频波浪的效果。

@Entry 
@Component 
struct Index { 
  private settings: RenderingContextSettings = new RenderingContextSettings(true) 
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings) 
  @State xoffset: number = 0 
  @State viewY: number = 220 / 2; 
  @State widths: number = 360 
  @State yoffset: number = 40; 
  @State intervalID: number = 0 
 
  startOnReady() { 
    this.context.beginPath(); 
    this.context.lineWidth = 3 
    //屏幕内波浪线 
    this.context.moveTo(this.xoffset, this.viewY) 
    this.context.quadraticCurveTo(this.widths / 4 + this.xoffset, this.viewY - this.yoffset, this.widths / 2 + this.xoffset, this.viewY) 
    this.context.moveTo(this.widths / 2 + this.xoffset, this.viewY) 
    this.context.quadraticCurveTo(this.widths / 4 * 3 + this.xoffset, this.viewY + this.yoffset, this.widths + this.xoffset, this.viewY) 
    this.context.moveTo(this.xoffset - this.widths, this.viewY) 
    //屏幕外波浪线 
    this.context.quadraticCurveTo(this.widths / 4 + this.xoffset - this.widths, this.viewY - this.yoffset, 
      this.widths / 2 + this.xoffset - this.widths, this.viewY) 
    this.context.moveTo(this.widths / 2 + this.xoffset - this.widths, this.viewY) 
    this.context.quadraticCurveTo(this.widths / 4 * 3 + this.xoffset - this.widths, this.viewY + this.yoffset, this.widths + this.xoffset - this.widths, this.viewY) 
    //抗锯齿的设置 
    this.context.imageSmoothingEnabled = true; 
    this.context.imageSmoothingQuality = 'medium' 
    this.context.stroke() 
  } 
 
  build() { 
    Column() { 
      Canvas(this.context).width(360).height(220).backgroundColor('#ffff00').onReady(() => { 
        this.startOnReady() 
      }) 
      Button("开始波浪线动画(" + this.xoffset + ")").onClick(() => { 
        this.intervalID = setInterval(() => { 
          this.context.clearRect(0, 0, 360, 250) 
          this.xoffset = this.xoffset + 10 
          this.startOnReady() 
          if (this.xoffset === 360) { 
            this.xoffset = 0 
          } 
          let s = this.widths / 4 + this.xoffset 
          let ss = this.viewY - this.yoffset 
          let sss = this.widths / 2 + this.xoffset 
          console.log(s + '-' + ss + '-' + sss + '-' + this.viewY) 
        }, 20); 
        this.xoffset = this.xoffset + 10 
      }).margin({ top: 40 }) 
      Button("停止波浪线动画").onClick(() => { 
        this.context.clearRect(0, 0, 360, 250) 
        clearInterval(this.intervalID) 
        this.xoffset = 0 
        this.startOnReady() 
      }).margin({ top: 40 }) 
    }.width('100%').height('100%') 
  } 
}
分享
微博
QQ
微信
回复
2024-08-29 17:02:08
相关问题
HarmonyOS 音频直通如何实现
146浏览 • 1回复 待解决
HarmonyOS 如何实现RippleView动画
326浏览 • 1回复 待解决
HarmonyOS 如何实现WaveView动画
359浏览 • 1回复 待解决
HarmonyOS 如何实现旋转动画
458浏览 • 1回复 待解决
HarmonyOS 如何实现动画集合?
30浏览 • 1回复 待解决
HarmonyOS如何实现动态缩放动画
563浏览 • 1回复 待解决
属性动画如何实现宽高动画效果
2044浏览 • 1回复 待解决
HarmonyOS实现后台播放音频
498浏览 • 1回复 待解决
鸿蒙-如何实现播放一段音频
11095浏览 • 2回复 待解决
HarmonyOS 如何实现放大缩小的动画
399浏览 • 1回复 待解决
HarmonyOS Canvas 实现动画
44浏览 • 1回复 待解决
如何应用属性动画实现宽高的动画
414浏览 • 1回复 待解决
如何实现动画转场效果
843浏览 • 1回复 待解决
SoundPool实现音频播放功能
1378浏览 • 1回复 待解决
文字动画效果如何实现
1896浏览 • 0回复 待解决
鸿蒙如何实现动画值变化
9443浏览 • 1回复 待解决
求教ArkUI如何实现组合动画
5515浏览 • 1回复 待解决
HarmonyOS 点赞动画实现方案
49浏览 • 1回复 待解决
AVPlayer实现音频播放(c++侧)
1353浏览 • 1回复 待解决
如何实现list的折叠动画效果
504浏览 • 1回复 待解决
在 ArkUl中如何实现动画效果?
147浏览 • 0回复 待解决