PlayerPage.ets 3.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import { deviceInfo } from '@kit.BasicServicesKit'
  2. import { hdsEffect } from '@kit.UIDesignKit'
  3. import { StrUtil } from '@pura/harmony-utils'
  4. @Component
  5. export struct PlayerPage {
  6. // 播放页拖拽关闭时的位移状态,由 LocalMusic 统一维护,页面只负责消费。
  7. @Prop translateY: number = 0
  8. // 是否启用播放页背景流光效果,避免页面组件反向依赖 LocalMusic 的实现细节。
  9. @Prop enableBackgroundEffect: boolean = false
  10. // 是否显示背景流光效果,和启用开关拆开,便于后续继续裁剪状态依赖。
  11. @Prop showBackgroundEffect: boolean = false
  12. // 背景流光控制器仍然由 LocalMusic 持有,独立页面只做承载。
  13. @Prop bgController: hdsEffect.ShaderEffectController | undefined = undefined
  14. // 新页面壳层也支持承载封面背景,便于 NewIndex 先接入独立的播放页容器。
  15. @Prop backgroundCover: string | undefined = ''
  16. @Prop backgroundCoverEnabled: boolean = false
  17. @Prop backgroundCoverFillMode: 'width' | 'height' | 'height-width' = 'width'
  18. @Prop pageBackgroundBlurStyle: BlurStyle = BlurStyle.NONE
  19. @Prop paddingTop: number = 0
  20. @Prop alignItemsValue: HorizontalAlign = HorizontalAlign.Center
  21. @Prop panOptions: PanGestureOptions = new PanGestureOptions()
  22. @BuilderParam contentBuilder: () => void
  23. // 页面拖拽和销毁清理动作通过回调下沉给 LocalMusic,保证业务状态仍在一个地方维护。
  24. onPanUpdate: (event?: GestureEvent) => void = (_event?: GestureEvent): void => {}
  25. onPanEnd: (event?: GestureEvent) => void = (_event?: GestureEvent): void => {}
  26. onDisappearCleanup: () => void = (): void => {}
  27. build() {
  28. Column() {
  29. // 播放页只负责壳层结构,内部内容逐步从 LocalMusic 迁移。
  30. this.contentBuilder()
  31. }
  32. .transition(TransitionEffect.asymmetric(
  33. TransitionEffect.opacity(1),
  34. TransitionEffect.OPACITY
  35. ))
  36. .visualEffect(this.enableBackgroundEffect && this.showBackgroundEffect && deviceInfo.sdkApiVersion >= 20 &&
  37. this.bgController
  38. ? new hdsEffect.HdsEffectBuilder()
  39. .shaderEffect({
  40. effectType: hdsEffect.EffectType.UV_BACKGROUND_FLOW_LIGHT,
  41. animation: {
  42. duration: 10000,
  43. iterations: -1,
  44. autoPlay: true,
  45. onFinish: () => {
  46. console.info('Succeeded in finishing')
  47. }
  48. },
  49. controller: this.bgController,
  50. })
  51. .buildEffect()
  52. : undefined)
  53. .height('100%')
  54. .width('100%')
  55. .padding({ top: this.paddingTop })
  56. .alignItems(this.alignItemsValue)
  57. .backgroundImage(this.backgroundCoverEnabled && StrUtil.isNotEmpty(this.backgroundCover)
  58. ? this.backgroundCover : null)
  59. .backgroundImageSize(this.backgroundCoverFillMode === 'height-width'
  60. ? { height: '150%', width: '100%' }
  61. : (this.backgroundCoverFillMode === 'height' ? { height: '150%' } : { width: '100%' }))
  62. .backgroundBlurStyle(this.pageBackgroundBlurStyle)
  63. .onDisAppear(() => {
  64. // 页面消失时统一回调外部清理拖拽中间态,避免残留到下一次打开。
  65. this.onDisappearCleanup()
  66. })
  67. .translate({ y: this.translateY })
  68. .gesture(
  69. // 播放页的关闭/切歌手势放在独立页面里承载,但具体业务判断仍交给 LocalMusic。
  70. PanGesture(this.panOptions)
  71. .onActionUpdate((event?: GestureEvent) => {
  72. this.onPanUpdate(event)
  73. })
  74. .onActionEnd((event?: GestureEvent) => {
  75. this.onPanEnd(event)
  76. })
  77. )
  78. }
  79. }