Implementing Spring Curve Animations in HarmonyOS ArkUI

Spring curve animations allow developers to create oscillating effects that exceed the target value before settling down, resulting in more natural and playful animations compared to standard easing curves. HarmonyOS ArkUI provides preset animation curves such as Linear, Ease, and EaseIn, but the spring curves generated from spring oscillator physics models offer superior interactivity and visual impact.

Understanding Spring Curve APIs

ArkUI provides two categories of spring curve APIs: springCurve for manual parameter configuration, and springMotion along with responsiveSpringMotion for automatic spring behavior generation.

Manual Configuration with springCurve

The springCurve API accepts four physical parameters:

springCurve(velocity: number, mass: number, stiffness: number, damping: number)
  • velocity: The initial velocity (v0) represents the speed of the object at a specific moment in time.
  • mass: The mass (m) of the entire spring system, including the spring itself and any attached objects.
  • stiffness: The spring constant (k) indicates the force generated per unit of extension or compression. Higher stiffness produces greater force for the same displacement.
  • damping: The damping coefficient (d) represents resistance to oscillation. This can result in undamped free vibration, underdamped decay, or overdamped slow decay.

The following example demonstrates horizontal movement with varying spring speeds:

import curves from '@ohos.curves';

@Entry
@Component
struct SpringAnimation {
  @State offsetX: number = 0;

  private animateMovement(speed: number) {
    this.offsetX = -1;
    animateTo({ duration: 2000, curve: curves.springCurve(speed, 1, 1, 1.2) }, () => {
      this.offsetX = 0;
    });
  }

  build() {
    Column() {
      Button("button")
        .fontSize(14)
        .width(100)
        .height(50)
        .margin(30)
        .translate({ x: this.offsetX })
      Row({ space: 50 }) {
        Button("jump 50")
          .fontSize(14)
          .onClick(() => {
            this.animateMovement(50);
          })
        Button("jump 200")
          .fontSize(14)
          .onClick(() => {
            this.animateMovement(200);
          })
      }.margin(30)
    }.height('100%').width('100%')
  }
}

Automatic Spring Motion with springMotion and responsiveSpringMotion

For automatic spring behavior, use the simplified APIs:

springMotion(response?: number, dampingFraction?: number, overlapDuration?: number)

responsiveSpringMotion(response?: number, dampingFraction?: number, overlapDuration?: number)
  • response: The natural vibration period (T) is the time for the spring to travel between extremes without external forces. Calculated as T = 2π√(m/k).
  • dampingFraction: The damping ratio (β) controls oscillation decay. Values include undamped (β = 0), underdamped (β < 2√(mk)), or overdamped (β > 2√(mk)). Higher values mean faster decay.
  • overlapDuration: The transition duration when blending consecutive spring animations together.

This example implements a draggable circle with responsive spring behavior:

import curves from '@ohos.curves';

@Entry
@Component
struct DraggableBall {
  @State posX: number = 100;
  @State posY: number = 100;
  ballSize: number = 50;

  build() {
    Column() {
      Circle({ width: this.ballSize, height: this.ballSize })
        .fill(Color.Blue)
        .position({ x: this.posX, y: this.posY })
        .onTouch((event: TouchEvent) => {
          if (event.type === TouchType.Move) {
            animateTo({ curve: curves.responsiveSpringMotion() }, () => {
              this.posX = event.touches[0].screenX - this.ballSize / 2;
              this.posY = event.touches[0].screenY - this.ballSize / 2;
            });
          } else if (event.type === TouchType.Up) {
            animateTo({ curve: curves.springMotion() }, () => {
              this.posX = 100;
              this.posY = 100;
            });
          }
        })
    }.width('100%').height('100%')
  }
}

The key difference between these two motion types lies in their use cases: responsiveSpringMotion provides immediate, snappy response during touch interactions, while springMotion offers smoother, more deliberate settilng behavior when releasing the finger from the screen.

Tags: HarmonyOS ArkUI animation SpringCurve springMotion

Posted on Mon, 05 Oct 2026 16:44:21 +0000 by kenwvs