FAB 酷炫展开和收敛动画有何思路? #HarmonyOS最强问答官# HarmonyOS 鸿蒙Next

FAB 酷炫展开和收敛动画有何思路? #HarmonyOS最强问答官# HarmonyOS 鸿蒙Next 我们的应用采用了经典且古典的 FloatingActionButton 导航.

视觉效果如下:

该导航效果包括 2 种状态: 展开和收敛.

而在展开和收敛的过程中有非常酷炫的动画效果.

想向大佬们讨教一下, 在 HarmonyOS NEXT 的 ArkUI 中, 要实现如此酷炫的效果, 应该从哪些方面入手?

3 回复

可通过设置 .foregroundFilter.contrast 这 2 个属性,可以实现水滴融合的效果;通过 this.getUIContext()?.animateTo 实现组件的移动,旋转,透明度变化的动画

import { uiEffect } from '@kit.ArkGraphics2D';

@Entry
@Component
struct HoverButtonExample {
  @State flag: boolean = true
  @State opacityValue: number = 0;
  @State BY1: number = 0
  @State BY2: number = 0
  @State BY3: number = 0
  @State BY4: number = 0
  @State angle: number = 0
  @State widthBottom: number = 80
  @State boxWidth: number = 100
  @State itemWidth: number = 60
  @State pad: number = 20
  @State backMove: number = 0
  @State backHeight: number = 50
  @State backWidth: number = 60
  @State distance: number = 100
  @State filterTest1: uiEffect.Filter = uiEffect.createFilter().blur(20)
  @State imageWidth: number = 20
  
  build() {
    Stack() {
      Column() {}
      .width(this.widthBottom)
      .height(this.widthBottom)
      .borderRadius(this.widthBottom / 2)
      .backgroundColor("#333")
      .foregroundFilter(this.filterTest1) // 通过 foregroundFilter 设置模糊效果
      
      Column() {}
      .width(this.itemWidth)
      .height(this.itemWidth)
      .translate({ y: this.BY2 })
      .foregroundFilter(this.filterTest1) // 通过 foregroundFilter 设置模糊效果
      .backgroundColor("#333")
      .borderRadius(30)
      
      Column() {}
      .width(this.itemWidth)
      .height(this.itemWidth)
      .translate({ y: this.BY3 })
      .foregroundFilter(this.filterTest1) // 通过 foregroundFilter 设置模糊效果
      .backgroundColor("#333")
      .borderRadius(30)
      
      Column() {}
      .width(this.itemWidth)
      .height(this.itemWidth)
      .translate({ y: this.BY4 })
      .foregroundFilter(this.filterTest1) // 通过 foregroundFilter 设置模糊效果
      .backgroundColor("#333")
      .borderRadius(30)
      
      Image($r('app.media.ic_public_arrow_left'))
        .width(this.imageWidth)
        .height(this.imageWidth)
        .rotate({ angle: this.angle })
        .zIndex(7)
      
      Image($r('app.media.ic_public_arrow_left'))
        .width(this.imageWidth)
        .height(this.imageWidth)
        .opacity(this.opacityValue)
        .zIndex(8)
        .translate({ y: this.BY2 })
      
      Image($r('app.media.ic_public_arrow_left'))
        .width(this.imageWidth)
        .height(this.imageWidth)
        .opacity(this.opacityValue)
        .zIndex(9)
        .translate({ y: this.BY3 })
      
      Image($r('app.media.ic_public_arrow_left'))
        .width(this.imageWidth)
        .height(this.imageWidth)
        .opacity(this.opacityValue)
        .zIndex(10)
        .translate({ y: this.BY4 })
    }
    .width(this.boxWidth)
    .height("100%")
    .contrast(20)
    .border({ color: "#333", width: 1 })
    .onClick(() => {
      if (this.flag) {
        this.getUIContext()?.animateTo({ curve: Curve.Friction, duration: 2000 }, () => {
          this.backMove = this.distance * 3 / 2
          this.backHeight += this.distance * 3
          this.backWidth = 0
          this.widthBottom = this.widthBottom - this.pad
          this.angle = 45
          this.BY2 = this.BY2 - this.distance
          this.BY3 = this.BY3 - this.distance * 2
          this.BY4 = this.BY4 - this.distance * 3
          this.flag = !this.flag
          this.opacityValue = 1
        })
      } else {
        this.getUIContext()?.animateTo({ curve: Curve.Friction, duration: 2000 }, () => {
          this.backMove = this.backMove - this.distance * 3 / 2
          this.backHeight -= this.distance * 3
          this.backWidth = this.itemWidth
          this.widthBottom = this.widthBottom + this.pad
          this.angle = 0
          this.BY2 = this.BY2 + this.distance
          this.BY3 = this.BY3 + this.distance * 2
          this.BY4 = this.BY4 + this.distance * 3
          this.flag = !this.flag
          this.opacityValue = 0
        })
      }
    })
  }
}

以上是初步分析结论,如有疑问可以展开回复,看到后会继续协助定位阻碍点。

开源网站上收录了UI、系统接口、Web、创新特性等场景化鸿蒙示例DEMO,开发中可以参考:https://gitee.com/scenario-samples/demo-index

更多关于FAB 酷炫展开和收敛动画有何思路? #HarmonyOS最强问答官# HarmonyOS 鸿蒙Next的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


开发者您好,该问题已反馈研发人员进一步分析,请耐心等待!

在HarmonyOS中实现FAB(Floating Action Button)的酷炫展开和收敛动画,可以通过使用ArkUI框架中的动画组件和属性来实现。ArkUI提供了多种动画效果,包括平移、缩放、旋转等,可以灵活组合使用。

  1. 展开动画:可以通过设置FAB的缩放(scale)和平移(translate)属性来实现。首先,将FAB的初始尺寸设置为较小,然后通过动画将其放大到目标尺寸。同时,可以通过平移动画将FAB从屏幕边缘移动到目标位置。使用animateTo方法可以平滑地过渡这些属性变化。

  2. 收敛动画:与展开动画相反,收敛动画可以通过将FAB从目标尺寸缩小到初始尺寸,并平移回屏幕边缘来实现。同样使用animateTo方法来控制动画的平滑过渡。

  3. 组合动画:可以通过组合多个动画效果来增强视觉体验。例如,在展开时同时添加旋转效果,或在收敛时添加透明度变化。ArkUI允许通过Animation组件和Keyframe来定义复杂的动画序列。

  4. 交互触发:动画的触发可以通过用户交互事件来实现,如点击FAB按钮后触发展开动画,再次点击时触发收敛动画。使用onClick事件监听器来处理用户交互。

  5. 性能优化:为了确保动画的流畅性,可以使用useNativeDriver属性来启用硬件加速,减少CPU的负担。

通过以上方法,可以在HarmonyOS中实现FAB的酷炫展开和收敛动画,提升用户体验。

回到顶部