DEV Community

Cover image for Get Width/Height in Page, Animation for Canvas Drawing, Overload Implementation
kouwei qing
kouwei qing

Posted on

Get Width/Height in Page, Animation for Canvas Drawing, Overload Implementation

[Daily HarmonyOS Next Knowledge] Get Width/Height in Page, Animation for Canvas Drawing, Overload Implementation, Search Term Highlighting, Countdown Effect

1. How to get the window width/height in a HarmonyOS Page?

Not the device dimensions, but the window size in split-screen (half/third) or floating window modes.

Use the getWindowproperties().windowRect() method to retrieve width and height properties:

// Example code snippet
const windowRect = this.context.getWindowStage().getMainWindow().getWindowProperties().windowRect;
const { width, height } = windowRect;
console.info(`Window width: ${width}, height: ${height}`);
Enter fullscreen mode Exit fullscreen mode

2. How to animate Canvas content changes in HarmonyOS?

Need to draw content with Canvas and apply animations when component state changes.

Reference demo for Canvas animations:

import curves from '@ohos.curves';

@Entry
@Component
struct AnimationDemo {
  @State animate: boolean = false; // Step 1: Declare state variables
  @State rotateValue: number = 0; // Rotation angle for component 1
  @State translateX: number = 0; // Translation offset for component 2
  @State opacityValue: number = 1; // Opacity for component 2
  private settings: RenderingContextSettings = new RenderingContextSettings(true);
  private context: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.settings); // Step 2: Bind state to animatable properties

  build() {
    Row() {
      // Component 1
      Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) {
        Canvas(this.context)
          .onReady(() => {
            this.context.fillRect(0, 0, 100, 100);
          })
      }
      .opacity(this.opacityValue)
      .rotate({ angle: this.rotateValue })
      .animation({ curve: curves.springMotion() }) // Enable property animation
      .backgroundColor('#317AF7')
      .width(100)
      .height(100)
      .borderRadius(30)
      .onClick(() => {
        this.animate = !this.animate;
        // Update state variables to trigger animations
        this.rotateValue = this.animate ? 90 : 0; // Rotation animation
        this.translateX = this.animate ? 50 : 0; // Translation animation
        this.opacityValue = this.animate ? 0.6 : 1; // Opacity animation
      })

      // Component 2
      Column() {
      }
      .justifyContent(FlexAlign.Center)
      .width(100)
      .height(100)
      .backgroundColor('#D94838')
      .borderRadius(30)
      .opacity(this.opacityValue)
      .translate({ x: this.translateX })
      .animation({ curve: curves.springMotion() })
    }
    .width('100%')
    .height('100%')
    .justifyContent(FlexAlign.Center)
  }
}
Enter fullscreen mode Exit fullscreen mode

3. How to implement method overloading in HarmonyOS ArkTS?

Use optional parameters to achieve overloading:

export class Test {
  private name: string = '';
  private age: number;

  constructor(name?: string, age: number = 18) {
    if (name) {
      this.name = name;
    }
    this.age = age;
  }

  getAge(): number {
    return this.age;
  }

  getName() {
    return this.name;
  }

  hasSkill(skills?: Array<string> | string): string {
    let skillsMsg = 'Reading';
    if (skills) {
      if (typeof skills === 'string') {
        skillsMsg += skills;
      } else {
        skills.forEach(s => {
          skillsMsg += '' + s;
        });
      }
    }
    return 'Skills: ' + skillsMsg;
  }
}

// Usage example
let t1 = new Test();
let t2 = new Test('t2Name');
let t3 = new Test('t3Name', 100);

console.log(`t1# name: ${t1.getName()}, age: ${t1.getAge()}, skills: ${t1.hasSkill()}`);
console.log(`t2# name: ${t2.getName()}, age: ${t2.getAge()}, skills: ${t2.hasSkill('Arithmetic')}`);
console.log(`t3# name: ${t3.getName()}, age: ${t3.getAge()}, skills: ${t3.hasSkill(['Singing', 'Dancing'])}`);
Enter fullscreen mode Exit fullscreen mode

4. How to highlight search terms with color in HarmonyOS?

Need to make search terms red in search results.

Method 1: Use Text with multiple Span components and add onClick events:

@Entry
@Component
struct DialogExample {
  build() {
    Column() {
      Text('Thank you for using!')
      Text() {
        Span('We highly value your personal information and privacy protection. In accordance with latest regulations, we updated the')
        Span('《Personal Information Protection Guidelines》').fontColor(Color.Blue)
          .onClick(() => {
            console.log('Click event triggered')
          })
      }
    }.width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

Method 2: Use RichText or RichEditor components:

Reference: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-richtext-V5

RichText parses and displays HTML-formatted text.

Use Cases:

  • Load and display HTML strings without extensive customization.
  • Supports limited generic properties and events. Constraints:
  • Mobile viewport defaults to 980px width. If RichText width is smaller, HTML content may scroll within the component.
  • To override defaults, add the following meta tag in HTML content:

5. How to implement a resettable countdown for verification codes in HarmonyOS?

After the countdown ends, clicking "Resend" should restart the countdown.

@Entry
@Component
struct Page {
  @State elapsedTime: number = 0;
  textTimerController: TextTimerController = new TextTimerController();

  build() {
    Column() {
      Row() {
        TextTimer({ isCountDown: true, count: 59000, controller: this.textTimerController })
          .format("ss")
          .fontColor($r("app.color.theme_color_m"))
          .onTimer((utc: number, elapsedTime: number) => {
            this.elapsedTime = elapsedTime;
          })
        Text($r("app.string.login"))
          .fontSize(15)
          .fontColor($r("app.color.theme_color_m"))
          .onClick(() => {
            this.textTimerController.start();
          })
      }
      .margin({ top: 25 })
      .visibility(this.elapsedTime === 59000 ? Visibility.None : Visibility.Visible);

      Button('Reset and Start')
        .onClick(() => {
          this.textTimerController.reset();
          this.textTimerController.start();
        });

      Text() {
        Span('1111111111111')
          .fontColor($r("app.color.theme_color_m"))
        Span('2222222222222')
          .fontColor($r("app.color.theme_color_m"))
          .onClick(() => {
            this.textTimerController.reset();
            this.textTimerController.start();
          })
      }
      .textAlign(TextAlign.Center)
      .fontSize(13)
      .margin({ top: 25 })
      .width("90%");
    }
    .width('100%')
    .height('100%');
  }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)