DEV Community

zhonghua
zhonghua

Posted on • Edited on

Practical Development of HarmonyOS: Dynamic Microphone Development Guide

Practical Development of HarmonyOS: Dynamic Microphone Development Guide

Foreword
In the HarmonyOS ecosystem, developers are constantly exploring and innovating to bring richer interactive experiences to users. Recently, I came up with the idea of creating a microphone component that dynamically changes with sound. Despite the lack of ready-made reference cases on the Internet, I decided to take the initiative to turn this idea into reality. This article will delve into the development process, sharing my practical experience and technical details.

I. Preparations
Before we begin, we need to prepare two images that will serve as the foundation for the dynamic effect of the microphone. Place these images in the entry/ets directory of the project and configure them accordingly in the code.

Image description

Image description

Final effect:

Uploading image

Code Example:

private img: ImageBitmap = new ImageBitmap("image/img.png");
private img2: ImageBitmap = new ImageBitmap("image/img_1.png");
Enter fullscreen mode Exit fullscreen mode

II. Understanding the Classes Needed for Drawing
To achieve the dynamic effect, we need to understand and use some key classes and objects. These classes will help us draw on the Canvas and process the effects.

RenderingContextSettings: Used to configure the CanvasRenderingContext2D object, including whether to enable anti-aliasing.

private settings: RenderingContextSettings = new RenderingContextSettings(true);
Enter fullscreen mode Exit fullscreen mode

CanvasRenderingContext2D: Used to create a drawing context, through which we can draw graphics in the Canvas.

private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
Enter fullscreen mode Exit fullscreen mode

OffscreenCanvas: An off-screen canvas that allows us to perform drawing operations without affecting the main thread.

private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600);
Enter fullscreen mode Exit fullscreen mode

III. Defining the Microphone Display Effect Rules
The dynamic effect of the microphone will change according to the intensity of the sound. We have defined five levels, from 0 to 5, each representing different sound intensities. To simulate this effect, we have written a function to randomly generate sound levels.

Simulated Sound Level Function:

generateRandomNumberUpToFive(): number {
  const randomInt = Math.floor(Math.random() * 5); // 0, 1, 2, 3, 4
  // There is a 1/5 chance of returning 5
  if (Math.random() < 0.2) {
    return 5;
  }
  return randomInt;
}
Enter fullscreen mode Exit fullscreen mode

To achieve the dynamic effect, we use a timer to update the sound level at regular intervals and start this process when the component is initialized.

Component Initialization:

@State @Watch('draw') level: number = 3;

aboutToAppear(): void {
  setInterval(() => {
    this.level = this.generateRandomNumberUpToFive();
  }, 300);
}
Enter fullscreen mode Exit fullscreen mode

IV. Key Code
When implementing the dynamic effect, we need to first clear the previous drawing effect and then draw the dynamic layer effect of the microphone according to the sound level. Finally, overlay these effects to display the final dynamic effect.

Drawing Logic:

draw() {
  this.context.clearRect(0, 0, 192, 192);
  let offContext = this.offCanvas.getContext("2d", this.settings);
  offContext.drawImage(this.img2, 0, 0, 192, 192);
  let h = this.level * 192 / 5;
  let imagedata = offContext.getImageData(0, h, 192, 192);
  offContext.drawImage(this.img, 0, 0, 192, 192);
  offContext.putImageData(imagedata, 0, h);
  let image = this.offCanvas.transferToImageBitmap();
  this.context.transferFromImageBitmap(image);
}
Enter fullscreen mode Exit fullscreen mode

V. Overall Code Effect
Integrate the above code into a component, ensuring that the background is drawn when the component is initialized and the dynamic effect is updated as needed.

Complete Component Code:

@Component
struct CanvasExample1 {
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings);
  private offCanvas: OffscreenCanvas = new OffscreenCanvas(600, 600);
  private img: ImageBitmap = new ImageBitmap("image/img.png");
  private img2: ImageBitmap = new ImageBitmap("image/img_1.png");

  @State @Watch('draw') level: number = 3;

  draw() {
    this.context.clearRect(0, 0, 192, 192);
    let offContext = this.offCanvas.getContext("2d", this.settings);
    offContext.drawImage(this.img2, 0, 0, 192, 192);
    let h = this.level * 192 / 5;
    let imagedata = offContext.getImageData(0, h, 192, 192);
    offContext.drawImage(this.img, 0, 0, 192, 192);
    offContext.putImageData(imagedata, 0, h);
    let image = this.offCanvas.transferToImageBitmap();
    this.context.transferFromImageBitmap(image);
  }

  generateRandomNumberUpToFive(): number {
    const randomInt = Math.floor(Math.random() * 5); // 0, 1, 2, 3, 4
    if (Math.random() < 0.2) {
      return 5;
    }
    return randomInt;
  }

  aboutToAppear(): void {
    setInterval(() => {
      this.level = this.generateRandomNumberUpToFive();
    }, 300);
  }

  build() {
    Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
      Canvas(this.context)
        .width('100%')
        .height('100%')
        .onReady(() => {
          let offContext = this.offCanvas.getContext("2d", this.settings);
          offContext.drawImage(this.img, 0, 0, 192, 192);
        });
    }
    .width('100%')
    .height('100%');
  }
}
Enter fullscreen mode Exit fullscreen mode

Summary
Through the detailed analysis of this article, we have not only implemented a dynamic sound-controlled microphone component but also gained a deep understanding of the drawing APIs and dynamic effect implementation methods in HarmonyOS. It is hoped that this article can provide inspiration and guidance for other developers and jointly promote the innovation and development of the HarmonyOS ecosystem.

Note on Image Links
I encountered some issues while trying to parse the provided image links. This problem might be related to the links themselves or the network connection. If you need the content of these links, please check the validity of the web links and try again. If you have any other questions or need further assistance with the topic, feel free to ask, and I'll be happy to help.

Top comments (0)