鸿蒙特效教程01-哔哩哔哩点赞与一键三连效果实现教程

简介: 本教程面向HarmonyOS初学者,详细讲解如何实现类似哔哩哔哩APP中的点赞与一键三连效果。内容涵盖基础布局、状态切换、点击动画、长按手势识别、旋转缩放动画以及粒子爆炸效果的实现。通过ArkUI布局系统、状态管理、手势处理和动画技术,逐步完成从简单到复杂的交互设计。最终效果包括图标变色、缩放、旋转及粒子动画,为用户提供流畅生动的体验。适合希望掌握HarmonyOS开发技巧的开发者学习参考。

鸿蒙特效教程01-哔哩哔哩点赞与一键三连效果实现教程

本教程适合HarmonyOS初学者,通过简单到复杂的步骤,一步步实现类似哔哩哔哩APP中的点赞及一键三连效果。

最终效果预览

我们将实现以下两个效果:

  1. 点击点赞按钮:实现点赞/取消点赞的切换效果,包含图标变色和缩放动画
  2. 长按点赞按钮:实现一键三连效果,包含旋转、缩放和粒子动画

特效01-一键三连-效果.gif

一、基础布局实现

首先,我们需要创建基本的界面布局。这一步非常简单,只需要放置一个点赞图标。

@Entry
@Component
struct BilibiliLike {
   
  build() {
   
    // 使用Stack布局,使元素居中对齐
    Stack({
    alignContent: Alignment.Center }) {
   
      // 点赞图标
      Image($r('app.media.ic_public_like')) 
        .width(50) // 设置图标宽度
        .aspectRatio(1) // 保持宽高比为1:1
        .objectFit(ImageFit.Contain) // 设置图片适应方式
    }
    .width('100%') // 容器占满宽度
    .height('100%') // 容器占满高度
    .backgroundColor('#f1f1f1') // 设置背景颜色为浅灰色
  }
}
AI 代码解读

这一步实现了最基础的布局,我们使用了Stack布局使元素居中,并添加了一个点赞图标。图标使用了系统资源$r('app.media.ic_public_like')

二、添加状态和颜色切换

接下来,我们添加状态变量来跟踪点赞状态,并实现点击时的颜色切换效果。

@Entry
@Component
struct BilibiliLike {
   
  // 是否已点赞状态
  @State isLiked: boolean = false
  // 未点赞时的颜色(灰色)
  @State unlikeColor: string = '#757575'
  // 点赞后的颜色(蓝色)
  @State likeColor: string = '#4eabe6'

  build() {
   
    Stack({
    alignContent: Alignment.Center }) {
   
      Image($r('app.media.ic_public_like'))
        .width(50)
        .aspectRatio(1)
        .objectFit(ImageFit.Contain)
        .fillColor(this.isLiked ? this.likeColor : this.unlikeColor) // 根据点赞状态设置颜色
        .onClick(() => {
   
          // 点击时切换点赞状态
          this.isLiked = !this.isLiked
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f1f1f1')
  }
}
AI 代码解读

这一步我们添加了:

  1. isLiked 状态变量,用于跟踪是否已点赞
  2. 两个颜色变量 unlikeColorlikeColor
  3. 在图标上添加 fillColor 属性,根据点赞状态切换颜色
  4. 为图标添加 onClick 事件,实现点击时切换点赞状态

现在点击图标时,图标会在灰色和蓝色之间切换,实现了基本的点赞/取消点赞效果。

三、添加点击动画效果

点击时的颜色变化已经实现了,但用户体验还不够好。我们需要添加一些动画效果,让点赞操作更加生动。

@Entry
@Component
struct BilibiliLike {
   
  @State isLiked: boolean = false
  @State unlikeColor: string = '#757575'
  @State likeColor: string = '#4eabe6'
  // 添加控制缩放的状态变量
  @State scaleValue: number = 1

  build() {
   
    Stack({
    alignContent: Alignment.Center }) {
   
      Image($r('app.media.ic_public_like'))
        .width(50)
        .aspectRatio(1)
        .objectFit(ImageFit.Contain)
        .fillColor(this.isLiked ? this.likeColor : this.unlikeColor)
        .scale({
    x: this.scaleValue, y: this.scaleValue }) // 添加缩放效果
        .onClick(() => {
   
          this.toggleLike() // 调用点赞切换方法
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f1f1f1')
  }

  // 处理点赞动画效果
  toggleLike() {
   
    // 切换点赞状态
    this.isLiked = !this.isLiked

    // 点赞动画 - 第一阶段:放大
    animateTo({
   
      duration: 300, // 动画持续300毫秒
      curve: Curve.Friction, // 使用摩擦曲线,效果更自然
      delay: 0 // 无延迟立即执行
    }, () => {
   
      this.scaleValue = 1.5 // 图标放大到1.5倍
    })

    // 点赞动画 - 第二阶段:恢复原大小
    animateTo({
   
      duration: 100, // 动画持续100毫秒
      curve: Curve.Friction, // 使用摩擦曲线
      delay: 300 // 延迟300毫秒执行,等第一阶段完成
    }, () => {
   
      this.scaleValue = 1 // 图标恢复到原始大小
    })
  }
}
AI 代码解读

这一步我们添加了:

  1. scaleValue 状态变量,用于控制图标的缩放比例
  2. 图标添加 scale 属性,绑定到 scaleValue 状态
  3. 创建了 toggleLike 方法,实现点赞状态切换和动画效果
  4. 使用 animateTo 方法创建两段动画:先放大,再恢复原大小

现在点击图标时,不仅会变色,还会有一个放大再缩小的动画效果,让交互更加生动。

四、添加长按手势识别

接下来,我们要实现长按触发一键三连的功能,首先需要添加长按手势识别。

@Entry
@Component
struct BilibiliLike {
   
  @State isLiked: boolean = false
  @State unlikeColor: string = '#757575'
  @State likeColor: string = '#4eabe6'
  @State scaleValue: number = 1
  // 添加一个标记三连效果的状态
  @State isTripleAction: boolean = false

  build() {
   
    Stack({
    alignContent: Alignment.Center }) {
   
      Image($r('app.media.ic_public_like'))
        .width(50)
        .aspectRatio(1)
        .objectFit(ImageFit.Contain)
        .fillColor(this.isLiked ? this.likeColor : this.unlikeColor)
        .scale({
    x: this.scaleValue, y: this.scaleValue })
        // 添加长按手势
        .gesture(
          LongPressGesture({
    repeat: false }) // 长按手势,不重复触发
            .onAction(() => {
   
              console.info("检测到长按事件")
              // 设置状态
              this.isTripleAction = true
              this.isLiked = true
            })
        )
        .onClick(() => {
   
          this.toggleLike()
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f1f1f1')
  }

  // 点赞动画方法保持不变
  toggleLike() {
   
    // 代码同上...
  }
}
AI 代码解读

这一步我们添加了:

  1. isTripleAction 状态变量,用于标记是否触发了一键三连效果
  2. 使用 gesture 方法添加长按手势识别
  3. 在长按触发时设置相关状态

现在,长按图标后,会将点赞状态设为已点赞,并触发三连状态,但还没有具体的动画效果。

五、添加长按动画效果

下一步,我们为长按添加更丰富的动画效果,包括旋转和缩放。

@Entry
@Component
struct BilibiliLike {
   
  @State isLiked: boolean = false
  @State isTripleAction: boolean = false
  @State scaleValue: number = 1
  @State unlikeColor: string = '#757575'
  @State likeColor: string = '#4eabe6'
  // 添加旋转角度状态
  @State rotation: number = 0

  build() {
   
    Stack({
    alignContent: Alignment.Center }) {
   
      Image($r('app.media.ic_public_like'))
        .width(50)
        .aspectRatio(1)
        .objectFit(ImageFit.Contain)
        .fillColor(this.isLiked ? this.likeColor : this.unlikeColor)
        .scale({
    x: this.scaleValue, y: this.scaleValue })
        .rotate({
    z: 1, angle: this.rotation }) // 添加旋转效果
        .gesture(
          LongPressGesture({
    repeat: false })
            .onAction(() => {
   
              this.triggerTripleAction() // 调用三连效果方法
            })
        )
        .onClick(() => {
   
          this.toggleLike()
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f1f1f1')
  }

  // 点赞动画方法保持不变
  toggleLike() {
   
    // 代码同上...
  }

  // 处理一键三连动画效果
  triggerTripleAction() {
   
    // 设置三连状态和点赞状态
    this.isTripleAction = true
    this.isLiked = true

    // 阶段一:点赞按钮放大并旋转
    animateTo({
   
      duration: 200, // 动画持续200毫秒
      curve: Curve.EaseInOut // 使用缓入缓出曲线
    }, () => {
   
      this.scaleValue = 1.8 // 图标放大到1.8倍
      this.rotation = 20 // 图标旋转20度
    })

    // 阶段二:点赞按钮缩小并恢复角度
    animateTo({
   
      duration: 100, // 动画持续100毫秒
      curve: Curve.EaseInOut, // 使用缓入缓出曲线
      delay: 200 // 延迟200毫秒,等阶段一完成
    }, () => {
   
      this.scaleValue = 1.2 // 图标缩小到1.2倍
      this.rotation = 0 // 图标恢复原始角度
    })

    // 阶段三:点赞按钮恢复原始大小
    animateTo({
   
      duration: 100, // 动画持续100毫秒
      curve: Curve.EaseInOut, // 使用缓入缓出曲线
      delay: 300 // 延迟300毫秒,等阶段二完成
    }, () => {
   
      this.scaleValue = 1 // 图标恢复原始大小
    })

    // 重置三连状态
    setTimeout(() => {
   
      this.isTripleAction = false
    }, 1000) // 延迟1000毫秒(1秒)执行
  }
}
AI 代码解读

这一步我们添加了:

  1. rotation 状态变量,用于控制图标的旋转角度
  2. 图标添加 rotate 属性,实现旋转效果
  3. 创建了 triggerTripleAction 方法,实现三连动画效果
  4. 三段连续动画,实现放大旋转、缩小恢复的动画序列

现在,长按图标会触发一系列动画:图标先放大并顺时针旋转,然后缩小并恢复原始角度,最后恢复原始大小,整个过程非常流畅。

六、添加粒子爆炸效果

最后,我们添加粒子爆炸效果,让一键三连的视觉效果更加丰富。

@Entry
@Component
struct BilibiliLike {
   
  @State isLiked: boolean = false
  @State isTripleAction: boolean = false
  @State scaleValue: number = 1
  @State rotation: number = 0
  @State unlikeColor: string = '#757575'
  @State likeColor: string = '#4eabe6'
  // 添加粒子透明度状态
  @State iconOpacity: number = 0

  build() {
   
    Stack({
    alignContent: Alignment.Center }) {
   
      // 粒子效果容器
      Column() {
   
        // 当触发三连效果时显示粒子
        if (this.isTripleAction) {
   
          // 创建8个粒子,均匀分布在圆周上
          ForEach([1, 2, 3, 4, 5, 6, 7, 8], (item: number) => {
   
            Circle()
              .width(8) // 粒子宽度
              .height(8) // 粒子高度
              .fill(this.likeColor) // 使用点赞颜色填充粒子
              // 使用三角函数计算粒子在圆周上的位置
              .position({
    x: 25 + 50 * Math.cos(item * Math.PI / 4), y: 25 + 50 * Math.sin(item * Math.PI / 4) })
              .opacity(this.iconOpacity) // 控制粒子的透明度
          })
        }
      }
      .width(50) // 设置容器宽度
      .height(50) // 设置容器高度

      // 点赞按钮
      Image($r('app.media.ic_public_like'))
        .width(50)
        .aspectRatio(1)
        .objectFit(ImageFit.Contain)
        .fillColor(this.isLiked ? this.likeColor : this.unlikeColor)
        .scale({
    x: this.scaleValue, y: this.scaleValue })
        .rotate({
    z: 1, angle: this.rotation })
        .gesture(
          LongPressGesture({
    repeat: false })
            .onAction(() => {
   
              this.triggerTripleAction()
            })
        )
        .onClick(() => {
   
          this.toggleLike()
        })
    }
    .width('100%')
    .height('100%')
    .backgroundColor('#f1f1f1')
  }

  // 点赞动画方法保持不变
  toggleLike() {
   
    // 代码同上...
  }

  // 处理一键三连动画效果
  triggerTripleAction() {
   
    // 设置三连状态和点赞状态
    this.isTripleAction = true
    this.isLiked = true

    // 点赞按钮动画部分保持不变
    // ...

    // 添加粒子出现动画
    animateTo({
   
      duration: 500, // 动画持续500毫秒
      curve: Curve.EaseOut, // 使用缓出曲线,开始快结束慢
      delay: 200 // 延迟200毫秒执行
    }, () => {
   
      this.iconOpacity = 1 // 粒子透明度变为1,完全显示
    })

    // 粒子消失动画
    animateTo({
   
      duration: 300, // 动画持续300毫秒
      curve: Curve.Linear, // 使用线性曲线,匀速变化
      delay: 700 // 延迟700毫秒,等粒子完全显示一段时间
    }, () => {
   
      this.iconOpacity = 0 // 粒子透明度变为0,完全消失
    })

    // 重置三连状态
    setTimeout(() => {
   
      this.isTripleAction = false
    }, 1000) // 延迟1000毫秒(1秒)执行
  }
}
AI 代码解读

这一步我们添加了:

  1. iconOpacity 状态变量,用于控制粒子的透明度
  2. 在Stack中添加粒子效果容器
  3. 使用ForEach和条件渲染,当触发三连效果时创建并显示粒子
  4. 使用三角函数计算粒子在圆周上的位置
  5. 添加粒子的动画效果,包括出现和消失

七、完整实现

最后,我们来看一下最终的完整代码实现。这里整合了前面所有的步骤,并添加了一些额外的细节优化。

/**
 * 哔哩哔哩点赞和一键三连效果组件
 * 实现功能:
 * 1. 普通点击: 实现点赞/取消点赞效果
 * 2. 长按: 触发一键三连效果(点赞+粒子动画)
 */
@Entry
@Component
struct BilibiliLike {
   
  // 是否已点赞状态
  @State isLiked: boolean = false
  // 是否触发一键三连效果状态
  @State isTripleAction: boolean = false
  // 控制图标缩放比例
  @State scaleValue: number = 1
  // 控制图标透明度
  @State opacityValue: number = 1
  // 控制图标X轴偏移量
  @State translateXValue: number = 0
  // 控制图标Y轴偏移量
  @State translateYValue: number = 0
  // 控制图标旋转角度
  @State rotation: number = 0
  // 控制粒子效果透明度
  @State iconOpacity: number = 0
  // 未点赞时的颜色(灰色)
  @State unlikeColor: string = '#757575'
  // 点赞后的颜色(蓝色)
  @State likeColor: string = '#4eabe6'

  build() {
   
    // 使用Stack布局,所有元素居中对齐
    Stack({
    alignContent: Alignment.Center }) {
   
      // 粒子效果容器
      Column() {
   
        // 当触发三连效果时显示粒子
        if (this.isTripleAction) {
   
          // 创建8个粒子,均匀分布在圆周上
          ForEach([1, 2, 3, 4, 5, 6, 7, 8], (item: number) => {
   
            Circle()
              .width(8) // 粒子宽度
              .height(8) // 粒子高度
              .fill(this.likeColor) // 使用点赞颜色填充粒子
              // 使用三角函数计算粒子在圆周上的位置
              .position({
    x: 25 + 50 * Math.cos(item * Math.PI / 4), y: 25 + 50 * Math.sin(item * Math.PI / 4) })
              .opacity(this.iconOpacity) // 控制粒子的透明度
          })
        }
      }
      .width(50) // 设置容器宽度
      .height(50) // 设置容器高度

      // 点赞按钮
      Image($r('app.media.ic_public_like')) // 使用点赞图标资源
        .width(50) // 设置图标宽度
        .aspectRatio(1) // 保持宽高比为1:1
        .objectFit(ImageFit.Contain) // 设置图片适应方式
        .fillColor(this.isLiked ? this.likeColor : this.unlikeColor) // 根据点赞状态设置颜色
        .scale({
    x: this.scaleValue, y: this.scaleValue }) // 设置缩放值
        .opacity(this.opacityValue) // 设置透明度
        .rotate({
    z: 1, angle: this.rotation }) // 设置旋转角度,绕z轴旋转
        .translate({
    x: this.translateXValue, y: this.translateYValue }) // 设置平移值
        // 添加长按手势,触发一键三连效果
        .gesture(
          LongPressGesture({
    repeat: false }) // 长按手势,不重复触发
            .onAction(() => {
   
              this.triggerTripleAction() // 调用三连效果方法
            })
        )
        // 添加点击事件,触发普通点赞效果
        .onClick(() => {
   
          this.toggleLike() // 调用点赞切换方法
        })
    }
    .width('100%') // 容器占满宽度
    .height('100%') // 容器占满高度
    .backgroundColor('#f1f1f1') // 设置背景颜色为浅灰色
    .expandSafeArea() // 扩展到安全区域
  }

  /**
   * 处理点赞/取消点赞动画效果
   * 点击时切换点赞状态并播放放大缩小动画
   */
  toggleLike() {
   
    // 切换点赞状态
    this.isLiked = !this.isLiked

    // 点赞动画 - 第一阶段:放大
    animateTo({
   
      duration: 300, // 动画持续300毫秒
      curve: Curve.Friction, // 使用摩擦曲线,效果更自然
      delay: 0 // 无延迟立即执行
    }, () => {
   
      this.scaleValue = 1.5 // 图标放大到1.5倍
    })

    // 点赞动画 - 第二阶段:恢复原大小
    animateTo({
   
      duration: 100, // 动画持续100毫秒
      curve: Curve.Friction, // 使用摩擦曲线
      delay: 300 // 延迟300毫秒执行,等第一阶段完成
    }, () => {
   
      this.scaleValue = 1 // 图标恢复到原始大小
    })
  }

  /**
   * 处理一键三连动画效果
   * 包含多个动画阶段:放大旋转、粒子出现与消失
   */
  triggerTripleAction() {
   
    // 设置三连状态和点赞状态
    this.isTripleAction = true // 启用三连效果
    this.isLiked = true // 设置为已点赞状态

    // 阶段一:点赞按钮放大并旋转
    animateTo({
   
      duration: 200, // 动画持续200毫秒
      curve: Curve.EaseInOut // 使用缓入缓出曲线
    }, () => {
   
      this.scaleValue = 1.8 // 图标放大到1.8倍
      this.rotation = 20 // 图标旋转20度
    })

    // 阶段二:点赞按钮缩小并恢复角度
    animateTo({
   
      duration: 100, // 动画持续100毫秒
      curve: Curve.EaseInOut, // 使用缓入缓出曲线
      delay: 200 // 延迟200毫秒,等阶段一完成
    }, () => {
   
      this.scaleValue = 1.2 // 图标缩小到1.2倍
      this.rotation = 0 // 图标恢复原始角度
    })

    // 阶段三:点赞按钮恢复原始大小
    animateTo({
   
      duration: 100, // 动画持续100毫秒
      curve: Curve.EaseInOut, // 使用缓入缓出曲线
      delay: 300 // 延迟300毫秒,等阶段二完成
    }, () => {
   
      this.scaleValue = 1 // 图标恢复原始大小
      this.isLiked = true // 确保点赞状态为true
    })

    // 阶段四:粒子出现动画
    animateTo({
   
      duration: 500, // 动画持续500毫秒
      curve: Curve.EaseOut, // 使用缓出曲线,开始快结束慢
      delay: 200 // 延迟200毫秒执行
    }, () => {
   
      this.iconOpacity = 1 // 粒子透明度变为1,完全显示
    })

    // 阶段五:粒子消失动画
    animateTo({
   
      duration: 300, // 动画持续300毫秒
      curve: Curve.Linear, // 使用线性曲线,匀速变化
      delay: 700 // 延迟700毫秒,等粒子完全显示一段时间
    }, () => {
   
      this.iconOpacity = 0 // 粒子透明度变为0,完全消失
    })

    // 延时重置三连状态,完成整个动画周期
    setTimeout(() => {
   
      this.isTripleAction = false // 关闭三连效果状态
    }, 1000) // 延迟1000毫秒(1秒)执行
  }
}
AI 代码解读

拓展与优化

以上是基本的实现,如果想进一步优化,可以考虑:

  1. 添加声音效果:在点赞和三连时添加声音反馈
  2. 添加震动反馈:利用设备振动提供触觉反馈
  3. 优化粒子效果:使用更复杂的粒子系统,例如随机大小、颜色和速度
  4. 添加投币和收藏图标:真正实现完整的"一键三连"效果,显示投币和收藏图标

总结

通过这个教程,我们从零开始实现了哔哩哔哩的点赞和一键三连效果。主要用到了以下技术:

  1. HarmonyOS的ArkUI布局系统
  2. 状态管理(@State)
  3. 手势处理(点击、长按)
  4. 动画系统(animateTo)
  5. 条件渲染
  6. 数学计算(用于粒子位置)

这些技术和概念不仅适用于这个特定效果,还可以应用于各种交互设计中。希望这个教程能帮助你更好地理解HarmonyOS开发,并创建出更加精美的应用界面!

megasu
+关注
目录
打赏
0
67
67
2
64
分享
相关文章
【HarmonyOS开发】ArkTS基础语法及使用(鸿蒙开发基础教程)
【HarmonyOS开发】ArkTS基础语法及使用(鸿蒙开发基础教程)
536 4
HarmonyOS ArkTS声明式UI开发实战教程
本文深入探讨了ArkTS作为HarmonyOS生态中新一代声明式UI开发框架的优势与应用。首先对比了声明式与命令式开发的区别,展示了ArkTS如何通过直观高效的代码提升可维护性。接着分析了其核心三要素:数据驱动、组件化和状态管理,并通过具体案例解析布局体系、交互组件开发技巧及复杂状态管理方案。最后,通过构建完整TODO应用实战,结合调试优化指南,帮助开发者掌握声明式UI设计精髓,感受ArkTS的独特魅力。文章鼓励读者通过“破坏性实验”建立声明式编程思维,共同推动HarmonyOS生态发展。
38 3
双十一钜惠!三门不可多得的HarmonyOS学习教程
今年双十一,各大商城优惠不断。这里介绍三门不可多得的HarmonyOS学习教程,都有非常大的折扣优惠。
113 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程(下)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程
270 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程(下)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程(中)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程
830 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程(中)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程(上)
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程
496 0
嵌入式linux/鸿蒙开发板(IMX6ULL)开发(三十一)驱动进化之路:设备树的引入及简明教程(上)
鸿蒙系统开发工具DevEco Studio 2.2下载/安装教程
鸿蒙开发包括鸿蒙应用开发(手机app)和鸿蒙设备开发(硬件开发)两大部分,其中设备开发又包括TV,音响,眼镜,手表,PC,平板,汽车,耳机以及未来的各种智能家居,手机作为一个超级终端,与各种设备实现互联,未来无论是在工作,学习,运动还是做家务,都会用到鸿蒙系统
576 1
鸿蒙系统开发工具DevEco Studio 2.2下载/安装教程
鸿蒙开发:什么是ArkTs?
本小结主要简单介绍了ArkTs语言的相关知识,都是一些概念性质的内容,大家作为一个了解即可
94 60
|
2天前
|
鸿蒙开发:远场通信服务rcp会话问题
总体来说,问题倒不是很大,解决起来也不是很麻烦,所以啊,老铁们,在实际的开发中,对于一些官方文档,还是建议多看,这样可以提前避免后续的不必要麻烦。
鸿蒙开发:远场通信服务rcp会话问题