HarmonyOS 鸿蒙Next叠卡动效

发布于 1周前 作者 caililin 来自 鸿蒙OS

HarmonyOS 鸿蒙Next叠卡动效 实现叠卡动效,能控制层叠数量和是否循环

2 回复
import curves from '@ohos.curves';

@Preview
@Entry
@Component
struct Index241009112752036 {
  @State message: string = 'Hello World'
  @State backgroundColors: Color[] = [Color.Pink, Color.Gray, Color.Orange]
  @State aheadIndex: number = 0;
  @State offsetX: number | string = 0;
  @State distanceInfo: number = 0;
  @State opacityInfo: number = 1
  @State isShow: Visibility = Visibility.Visible

  build() {
    Row() {
      Stack({ alignContent: Alignment.Start }) {
        ForEach(this.backgroundColors, (item: Color, index: number) {
          Row() {
            Text("1111")
              .width('100%')
              .height('100%')
              .fontSize(50)
              .textAlign(TextAlign.Center)
              .backgroundColor(item)
              .border({ width: 2, color: Color.Blue, radius: 10 })
              .opacity(this.getOpacityInfo(index))
              .scale({ x: this.getScale(index), y: this.getScale(index), centerX: 0 }) // 两轴尺寸缩放比例
          }
          .offset({ x: this.getOffsetX(index), y: 0 }) // 偏移距离
          .zIndex(this.getZIndex(index)) // z序控制stack层级关系,越大越靠上
        }, (item: Color) => item.toString())
      }
      .width("100%")
      .gesture(
        PanGesture({ direction: PanDirection.Horizontal, distance: 1 })
          .onActionStart((event?: GestureEvent) => {
            this.handlePanGestureStart(event?.offsetX);
          })
          .onActionUpdate((event?: GestureEvent) => {
            this.handlePanGestureUpdate(event?.offsetX);
          })
          .onActionEnd((event?: GestureEvent) => {
            this.handlePanGestureEnd(event?.offsetX);
          })
      )
    }
    .height("20%")
    .padding({ top: 5, left: 5, right: 5 })
  }

  getRealIndex(index: number): number {
    if (index < this.aheadIndex) {
      if (index === 0) {
        if (this.aheadIndex === 1) {
          return 2
        } else if (this.aheadIndex === 2) {
          return 1
        }
      } else if (index === 1) {
        return 2
      }
    }
    return index - this.aheadIndex;
  }

  getOpacityInfo(index: number): number {
    if (index == this.aheadIndex) {
      if (this.offsetX > 0 && this.offsetX <= 10) {
        this.opacityInfo = 0
        return this.opacityInfo
      }
      if (this.offsetX > 10) {
        animateTo({ curve: Curve.Linear, duration: 1 }, () => {
          this.opacityInfo = 1
        })
        return this.opacityInfo
      }
    }
    return 1
  }

  getScale(index: number): number {
    let width = 1 - (this.getRealIndex(index) + 1) * 0.05;
    if (index !== this.aheadIndex) {
      width = width + (this.distanceInfo / 180) * 0.05
    }
    return width;
  }

  getOffsetX(index: number): number | string {
    let realIndex = this.getRealIndex(index);
    console.log(`===indexIndex:${index}`)
    console.log(`===realIndex:${realIndex}`)
    console.log(`===offsetX:${this.offsetX}`)
    if (index == this.aheadIndex) {
      if (this.offsetX < 0) {
        return this.offsetX;
      }
      if (this.offsetX > 0) {
        return Number(this.offsetX) - 500
      }
    }
    let dis = realIndex * 25
    dis = dis - (this.distanceInfo / 180) * 25
    return dis;
  }

  getZIndex(index: number): number {
    console.log(`-zIndex:${this.aheadIndex}`)
    console.log(`zIndex:${-this.getRealIndex(index)}`)
    return -this.getRealIndex(index);
  }

  handlePanGestureStart(offsetX?: number): void {
    if (!offsetX) {
      return;
    }
    console.log(`Start offsetX:${offsetX}`)

    if (offsetX > 0) {
      this.aheadIndex = this.aheadIndex == 0 ? 2 : this.aheadIndex - 1;
 
    }
  }

  handlePanGestureUpdate(offsetX?: number): void {
    if (!offsetX) {
      return
    }
    if (offsetX > 0) {
      this.distanceInfo = offsetX
      animateTo({ curve: curves.springMotion() }, () => {
        this.offsetX = offsetX;
        console.log(`Update offsetX00:${this.offsetX}`)
      })
    }

    if (offsetX < 0) {
      console.log(`Update offsetX:${offsetX}`)
      this.distanceInfo = -offsetX
      animateTo({ curve: curves.springMotion() }, () => {
        this.offsetX = offsetX!;
        console.log(`Update offsetX00:${this.offsetX}`)
      })
    }
  }

  handlePanGestureEnd(offsetX?: number): void {
    if (!offsetX) {
      return;
    }
    console.log(`End offsetX:${offsetX}`)
    if (offsetX < 0) {
      if (offsetX < -180) {
        animateTo({ curve: curves.springMotion(), duration: 100 }, () => {
          this.offsetX = "-100%";
          console.log("swipe next")
          this.aheadIndex = this.aheadIndex == this.backgroundColors.length - 1 ? 0 : this.aheadIndex + 1;
          this.offsetX = 0;
          this.distanceInfo = 0
        }) 
      } else {
        animateTo({ curve: curves.springMotion() }, () => {
          this.offsetX = 0;
          this.distanceInfo = 0
        })
      }
    }
    if (offsetX > 0) {
      if (offsetX > 180) {
        animateTo({ curve: curves.springMotion(), duration: 100 }, () => {
          this.offsetX = "100%";     
          this.distanceInfo = 0
        })
      } else {
        animateTo({ curve: curves.springMotion() }, () => {
          this.aheadIndex = this.aheadIndex == this.backgroundColors.length - 1 ? 0 : this.aheadIndex + 1;
          this.offsetX = 0;
          this.distanceInfo = 0
        })
      }
    }
  }
}

更多关于HarmonyOS 鸿蒙Next叠卡动效的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


针对帖子标题“HarmonyOS 鸿蒙Next叠卡动效”的问题,以下是专业且简洁的回答:

HarmonyOS 鸿蒙Next叠卡动效是鸿蒙操作系统中一种独特的用户界面交互效果。该动效通过平滑地叠加和展开卡片,为用户提供直观且富有吸引力的视觉体验。

在鸿蒙系统中,叠卡动效通常应用于多任务管理、应用切换或信息展示等场景。当用户进行这些操作时,系统会以动画形式展示卡片的叠加和展开过程,使得界面过渡更加自然流畅。

要实现或调整鸿蒙Next叠卡动效,开发者需要熟悉鸿蒙系统的动画框架和界面布局技术。这包括了解鸿蒙系统的动画资源、动画控制器以及如何通过代码或XML布局文件来定义和触发动画效果。

此外,鸿蒙系统还提供了丰富的API和工具,帮助开发者自定义和优化动效。开发者可以根据应用需求,调整动画的持续时间、速度曲线、透明度等参数,以实现理想的叠卡动效。

需要注意的是,鸿蒙系统的动效实现可能因版本和设备而异。因此,开发者在设计和实现叠卡动效时,应确保兼容性和性能优化。

如果问题依旧没法解决请联系官网客服,官网地址是:https://www.itying.com/category-93-b0.html。

回到顶部