Jelajahi Sumber

播放条和播放页的动画效果优化

onecold 4 bulan lalu
induk
melakukan
cdb8759ae7

+ 133 - 36
entry/src/main/ets/pages/NewIndex.ets

@@ -61,6 +61,7 @@ import { PointLightDefaultButton } from '../view/PointLight/PointLightDeFaultBut
 import { PointLightContentButton } from '../view/PointLight/PointLightContentButton';
 import { FindView } from '../view/FindView';
 import { hdsEffect } from '@kit.UIDesignKit';
+import { resolveMiniPlayerMorphTarget } from '../common/util/PlayerDismissHelper';
 
 // import { FFmpeg, FFProgressMessageParser } from '@sj/ffmpeg';
 
@@ -89,6 +90,11 @@ struct NewIndex {
   @State isShowPrecious: boolean = false //播控条显示上一首按钮
   @State bottomBarHeight: number = 70;
   @State miniPlayerScaleX: number = 1;
+  @State miniPlayerScaleY: number = 1;
+  @State miniPlayerOpacity: number = 1;
+  @State miniPlayerBorderRadius: number = 200;
+  @State miniPlayerProxySize: number = 0;
+  @State miniPlayerProxyOpacity: number = 0;
   @State isMiniPlayerMounted: boolean = true;
   @StorageProp('bottomSafeHeight') bottomSafeHeight: number = 0;
   @Provide cover: string | undefined = '';
@@ -173,7 +179,9 @@ struct NewIndex {
   })
   @State @Watch('tabSelectedIndexesChanged') tabSelectedIndexes: number[] = [0]
   private miniPlayerAnimationTimer: number = -1;
-  private readonly miniPlayerAnimationDuration: number = 320;
+  private miniPlayerCleanupTimer: number = -1;
+  private readonly miniPlayerMorphDuration: number = 220;
+  private readonly miniPlayerDotDuration: number = 140;
   //当胶囊按钮的选择发生变化时调用此函数
   tabSelectedIndexesChanged() {
     if(this.tabSelectedIndexes[0]==1){
@@ -581,6 +589,33 @@ struct NewIndex {
       clearTimeout(this.miniPlayerAnimationTimer)
       this.miniPlayerAnimationTimer = -1
     }
+    if (this.miniPlayerCleanupTimer >= 0) {
+      clearTimeout(this.miniPlayerCleanupTimer)
+      this.miniPlayerCleanupTimer = -1
+    }
+  }
+
+  private resolveMiniPlayerMorphMetrics() {
+    const viewportWidthVp = this.windowWidth > 0 ? px2vp(this.windowWidth) : 360
+    const miniPlayerHeightVp = this.bottomBarHeight > 0 ? this.bottomBarHeight : 70
+    return resolveMiniPlayerMorphTarget(viewportWidthVp, 0.9, miniPlayerHeightVp)
+  }
+
+  private resetMiniPlayerAnimationState(): void {
+    this.miniPlayerScaleX = 1
+    this.miniPlayerScaleY = 1
+    this.miniPlayerOpacity = 1
+    this.miniPlayerBorderRadius = 200
+    this.miniPlayerProxySize = 0
+    this.miniPlayerProxyOpacity = 0
+  }
+
+  private isMiniPlayerFullyVisible(): boolean {
+    return this.isMiniPlayerMounted
+      && this.miniPlayerOpacity >= 0.99
+      && this.miniPlayerScaleX >= 0.999
+      && this.miniPlayerScaleY >= 0.999
+      && this.miniPlayerProxySize <= 0
   }
 
   private shouldShowMiniPlayer(): boolean {
@@ -589,41 +624,108 @@ struct NewIndex {
 
   private syncMiniPlayerVisibility(animated: boolean = true): void {
     const shouldShow = this.shouldShowMiniPlayer()
+    const target = this.resolveMiniPlayerMorphMetrics()
     this.clearMiniPlayerAnimationTimer()
     if (!animated) {
       this.isMiniPlayerMounted = shouldShow
-      this.miniPlayerScaleX = shouldShow ? 1 : 0
+      this.resetMiniPlayerAnimationState()
       return
     }
     if (shouldShow) {
+      if (this.isMiniPlayerFullyVisible()) {
+        return
+      }
       if (!this.isMiniPlayerMounted) {
         this.isMiniPlayerMounted = true
-        this.miniPlayerScaleX = 0
+        this.miniPlayerScaleX = target.circleScaleX
+        this.miniPlayerScaleY = target.circleScaleY
+        this.miniPlayerOpacity = 0
+        this.miniPlayerBorderRadius = target.circleDiameter / 2
+        this.miniPlayerProxySize = target.dotDiameter
+        this.miniPlayerProxyOpacity = 1
+      } else if (this.miniPlayerProxySize <= 0) {
+        this.miniPlayerProxySize = target.circleDiameter
+        this.miniPlayerProxyOpacity = 1
       }
       this.getUIContext()?.animateTo({
-        duration: this.miniPlayerAnimationDuration,
-        curve: Curve.Friction
+        duration: this.miniPlayerDotDuration,
+        curve: Curve.Sharp
       }, () => {
-        this.miniPlayerScaleX = 1
+        this.miniPlayerProxySize = target.circleDiameter
+        this.miniPlayerProxyOpacity = 1
       })
+      this.miniPlayerAnimationTimer = setTimeout(() => {
+        this.miniPlayerAnimationTimer = -1
+        this.getUIContext()?.animateTo({
+          duration: this.miniPlayerMorphDuration,
+          curve: Curve.Friction
+        }, () => {
+          this.miniPlayerScaleX = 1
+          this.miniPlayerScaleY = 1
+          this.miniPlayerOpacity = 1
+          this.miniPlayerBorderRadius = 200
+          this.miniPlayerProxySize = target.circleDiameter
+          this.miniPlayerProxyOpacity = 0
+        })
+      }, this.miniPlayerDotDuration + 16)
       return
     }
     if (!this.isMiniPlayerMounted) {
-      this.miniPlayerScaleX = 0
+      this.resetMiniPlayerAnimationState()
       return
     }
     this.getUIContext()?.animateTo({
-      duration: this.miniPlayerAnimationDuration,
+      duration: this.miniPlayerMorphDuration,
       curve: Curve.Friction
     }, () => {
-      this.miniPlayerScaleX = 0
+      this.miniPlayerScaleX = target.circleScaleX
+      this.miniPlayerScaleY = target.circleScaleY
+      this.miniPlayerOpacity = 0
+      this.miniPlayerBorderRadius = target.circleDiameter / 2
+      this.miniPlayerProxySize = target.circleDiameter
+      this.miniPlayerProxyOpacity = 1
     })
     this.miniPlayerAnimationTimer = setTimeout(() => {
       this.miniPlayerAnimationTimer = -1
-      if (!this.shouldShowMiniPlayer()) {
-        this.isMiniPlayerMounted = false
-      }
-    }, this.miniPlayerAnimationDuration + 16)
+      this.miniPlayerOpacity = 0
+      this.miniPlayerProxySize = target.circleDiameter
+      this.miniPlayerProxyOpacity = 1
+      this.getUIContext()?.animateTo({
+        duration: this.miniPlayerDotDuration,
+        curve: Curve.EaseIn
+      }, () => {
+        this.miniPlayerProxySize = target.dotDiameter
+        this.miniPlayerProxyOpacity = 0
+      })
+      this.miniPlayerCleanupTimer = setTimeout(() => {
+        this.miniPlayerCleanupTimer = -1
+        if (!this.shouldShowMiniPlayer()) {
+          this.isMiniPlayerMounted = false
+        }
+        this.resetMiniPlayerAnimationState()
+      }, this.miniPlayerDotDuration + 16)
+    }, this.miniPlayerMorphDuration + 16)
+  }
+
+  @Builder
+  private MiniPlayerMorphProxyDot() {
+    Stack({ alignContent: Alignment.Center }) {
+      Image(StrUtil.isNotEmpty(this.cover) ? this.cover as string : $r('app.media.alt'))
+        .width('100%')
+        .height('100%')
+        .objectFit(ImageFit.Cover)
+        .alt($r('app.media.alt'))
+    }
+    .width(this.miniPlayerProxySize)
+    .height(this.miniPlayerProxySize)
+    .borderRadius(this.miniPlayerProxySize)
+    .clip(true)
+    .opacity(this.miniPlayerProxyOpacity)
+    .shadow({
+      radius: 18,
+      type: ShadowType.BLUR,
+      color: 'on_primary'
+    })
   }
 
   @Builder
@@ -713,35 +815,30 @@ struct NewIndex {
       Stack() {
         this.ContentBuild()
         if (this.isMiniPlayerMounted) {
-          Stack() {
+          Stack({ alignContent: Alignment.Center }) {
+            Stack() {
+              this.PlayController()
+            }
+            .width('100%')
+            .height('100%')
+            .borderRadius(this.miniPlayerBorderRadius)
+            .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK)
+            .backgroundImage(StrUtil.isEmpty(this.cover) ?$r('app.media.alt'):this.cover)
+            .backgroundImageSize( {  width: '100%' })
+            .scale({ x: this.miniPlayerScaleX, y: this.miniPlayerScaleY, centerX: '50%', centerY: '50%' })
+            .opacity(Math.min(0.99, this.miniPlayerOpacity))
+            .clip(true)
+            .clickEffect({ level: ClickEffectLevel.HEAVY })
 
-            this.PlayController()
+            if (this.miniPlayerProxySize > 0) {
+              this.MiniPlayerMorphProxyDot()
+            }
           }
           .width('90%')
+          .height(this.bottomBarHeight)
           .borderRadius(200)
           .margin({ bottom:DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_2IN1||this.curDisplayIsHiCar
             ? 30 :this.bottomSafeHeight })
-          .backgroundBlurStyle(BlurStyle.BACKGROUND_ULTRA_THICK)
-          .backgroundImage(StrUtil.isEmpty(this.cover) ?undefined:this.cover)
-          .visualEffect(deviceInfo.sdkApiVersion>=20&&this.bgController&&StrUtil.isEmpty(this.cover)?
-            new hdsEffect.HdsEffectBuilder()
-              .shaderEffect({
-                effectType: hdsEffect.EffectType.UV_BACKGROUND_FLOW_LIGHT,
-                animation: {
-                  duration: 10000,
-                  iterations: -1,
-                  autoPlay: true,
-                  onFinish: ()=> {
-                    console.info('Succeeded in finishing');
-                  }
-                },
-                controller: this.bgController,
-              })
-              .buildEffect():null)
-          .backgroundImageSize( {  width: '100%' })
-          .scale({ x: this.miniPlayerScaleX, y: 1, centerX: '50%', centerY: '50%' })
-          .opacity(0.99)
-          .clickEffect({ level: ClickEffectLevel.HEAVY })
         }
       }
       .alignContent(Alignment.Bottom)

+ 1 - 1
entry/src/main/ets/pages/SettingPage.ets

@@ -309,7 +309,7 @@ export struct SettingPage {
     this.isCircleBtn = PreferencesUtil.getBooleanSync(SettingPage.IS_CIRCLE_BTN, true)
     this.isShowTitleBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_TITLTBAR, false)
     this.isShowAllBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_ALLBAR, true)
-    this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, true)
+    this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, false)
     this.isShowSingleLineLyric = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SLLYRIC, false)
     this.isCoverTopBig = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP_BIG, false)
     this.longPressSpeed = PreferencesUtil.getNumberSync(SettingPage.LONG_PRESS_SPEED, 3)

+ 127 - 48
entry/src/main/ets/view/LocalMusic.ets

@@ -115,7 +115,7 @@ import '../common/network/RemoteCacheRegistry';
 import { ServerLogUtil } from '../common/util/ServerLogUtil';
 import { lyricService, SongData } from '../common/service/LyricService';
 import { shouldResolveRemoteLyricOnPlay, tryResolveRemotePlaybackLyric } from '../common/util/RemotePlaybackLyricUtil';
-import { resolvePlayerDismissTarget } from '../common/util/PlayerDismissHelper';
+import { resolvePlayerDismissMorphTarget } from '../common/util/PlayerDismissHelper';
 import {
   cloneVideoItem,
   preloadNextSongIfNeeded,
@@ -774,8 +774,12 @@ export struct LocalMusic {
   @StorageLink('songList') songList: Array<VideoItem> = [];
   @State translateY: number = 0;
   @State playDismissScale: number = 1;
+  @State playDismissScaleY: number = 1;
   @State playDismissOpacity: number = 1;
   @State playDismissTranslateX: number = 0;
+  @State playDismissBorderRadius: number = 0;
+  @State playDismissProxySize: number = 0;
+  @State playDismissProxyOpacity: number = 0;
   @State isShowSheet: boolean = false;
   @State isShowSheetView: boolean = false;
   @State isShowLyricCopySheet: boolean = false;
@@ -784,9 +788,12 @@ export struct LocalMusic {
   @State isShowTimeCloseView: boolean = false;
   private panOption: PanGestureOptions = new PanGestureOptions({ direction: PanDirection.Vertical });
   private playDismissTimer: number = -1;
-  private readonly playDismissDuration: number = 420;
+  private readonly playDismissContentDuration: number = 260;
+  private readonly playDismissDotDuration: number = 160;
   private playOpenFromMiniBarPending: boolean = false;
   private playOpenTimer: number = -1;
+  private readonly playOpenDotDuration: number = 120;
+  private readonly playOpenExpandDuration: number = 300;
   @StorageLink('currIndex') curIndex: number = 0;
   @Consume isShowDrawer: boolean;
   @Consume offsetX: number;
@@ -1529,7 +1536,7 @@ export struct LocalMusic {
     this.isShowAllBar = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_ALLBAR, true)
     this.twoFingerType = PreferencesUtil.getNumberSync(SettingPage.TWO_FINGER_TYPE, 3)
     this.isCircleBtn = PreferencesUtil.getBooleanSync(SettingPage.IS_CIRCLE_BTN, true)
-    this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, true)
+    this.isShowPlayPageBack = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_PLAYPAGE_BACK, false)
     this.isCoverTopBig = PreferencesUtil.getBooleanSync(SettingPage.IS_COVER_TOP_BIG, false)
     this.isShowSingleLineLyric = PreferencesUtil.getBooleanSync(SettingPage.IS_SHOW_SLLYRIC, false)
     this.isEnableWordByWordLyric = PreferencesUtil.getBooleanSync(SettingPage.IS_ENABLE_WORD_BY_WORD_LYRIC, true)
@@ -9002,7 +9009,7 @@ export struct LocalMusic {
     const viewportHeightVp = this.windowHeight > 0 ? px2vp(this.windowHeight) : 800
     const useFixedBottomMargin = DeviceUtil.getDeviceType() === resourceManager.DeviceType.DEVICE_TYPE_2IN1
       || this.curDisplayIsHiCar
-    return resolvePlayerDismissTarget(viewportWidthVp, viewportHeightVp, this.bottomSafeHeight, useFixedBottomMargin)
+    return resolvePlayerDismissMorphTarget(viewportWidthVp, viewportHeightVp, this.bottomSafeHeight, useFixedBottomMargin)
   }
 
   private clearPlayDismissTimer(): void {
@@ -9026,7 +9033,11 @@ export struct LocalMusic {
     this.translateY = 0
     this.playDismissTranslateX = 0
     this.playDismissScale = 1
+    this.playDismissScaleY = 1
     this.playDismissOpacity = 1
+    this.playDismissBorderRadius = 0
+    this.playDismissProxySize = 0
+    this.playDismissProxyOpacity = 0
     this.scaleValueImage = 1
     this.scaleValueText = 1
     this.playDragUiOpacity = 1
@@ -9037,30 +9048,50 @@ export struct LocalMusic {
     this.playOpenFromMiniBarPending = true
     this.translateY = target.translateY
     this.playDismissTranslateX = target.translateX
-    this.playDismissScale = target.scale
+    this.playDismissScale = target.circleScaleX
+    this.playDismissScaleY = target.circleScaleY
     this.playDismissOpacity = 0
+    this.playDismissBorderRadius = target.circleDiameter / 2
+    this.playDismissProxySize = target.dotDiameter
+    this.playDismissProxyOpacity = 1
     this.playDragUiOpacity = 0
-    this.scaleValueImage = Math.max(0.72, target.scale)
-    this.scaleValueText = Math.max(0.88, target.scale)
+    this.scaleValueImage = Math.max(0.72, target.circleScaleX)
+    this.scaleValueText = Math.max(0.88, target.circleScaleY)
   }
 
   private startPlayerViewOpenAnimationIfNeeded(): void {
     if (!this.playOpenFromMiniBarPending) {
       return
     }
+    const target = this.resolveMiniBarDismissTarget()
     this.playOpenFromMiniBarPending = false
     this.getUIContext()?.animateTo({
-      duration: this.playDismissDuration,
+      duration: this.playOpenDotDuration,
       curve: Curve.Sharp
     }, () => {
-      this.translateY = 0
-      this.playDismissTranslateX = 0
-      this.playDismissScale = 1
-      this.playDismissOpacity = 1
-      this.playDragUiOpacity = 1
-      this.scaleValueImage = 1
-      this.scaleValueText = 1
+      this.playDismissProxySize = target.circleDiameter
+      this.playDismissProxyOpacity = 1
+      this.playDismissOpacity = 0
     })
+    this.playOpenTimer = setTimeout(() => {
+      this.playOpenTimer = -1
+      this.getUIContext()?.animateTo({
+        duration: this.playOpenExpandDuration,
+        curve: Curve.Friction
+      }, () => {
+        this.playDismissProxySize = target.circleDiameter
+        this.playDismissProxyOpacity = 0
+        this.translateY = 0
+        this.playDismissTranslateX = 0
+        this.playDismissScale = 1
+        this.playDismissScaleY = 1
+        this.playDismissOpacity = 1
+        this.playDismissBorderRadius = 0
+        this.playDragUiOpacity = 1
+        this.scaleValueImage = 1
+        this.scaleValueText = 1
+      })
+    }, this.playOpenDotDuration + 16)
   }
 
   setShowPlayTrue(fromMiniBar: boolean = false){
@@ -9091,23 +9122,40 @@ export struct LocalMusic {
     const target = this.resolveMiniBarDismissTarget()
 
     this.clearPlayDismissTimer()
+    this.clearPlayOpenTimer()
     this.getUIContext()?.animateTo({
-      duration: this.playDismissDuration,
+      duration: this.playDismissContentDuration,
       curve: Curve.Sharp
     }, () => {
       this.translateY = target.translateY
       this.playDismissTranslateX = target.translateX
-      this.playDismissScale = target.scale
-      this.playDismissOpacity = 0
+      this.playDismissScale = target.circleScaleX
+      this.playDismissScaleY = target.circleScaleY
+      this.playDismissOpacity = 0.12
+      this.playDismissBorderRadius = target.circleDiameter / 2
+      this.playDismissProxySize = target.circleDiameter
+      this.playDismissProxyOpacity = 1
       this.playDragUiOpacity = 0
-      this.scaleValueImage = Math.max(0.72, target.scale)
-      this.scaleValueText = Math.max(0.88, target.scale)
+      this.scaleValueImage = Math.max(0.72, target.circleScaleX)
+      this.scaleValueText = Math.max(0.88, target.circleScaleY)
     })
     this.playDismissTimer = setTimeout(() => {
-      this.playDismissTimer = -1
-      this.isShowPlay = false
-      this.isShowCoverScaleGuide = false
-    }, this.playDismissDuration + 16)
+      this.playDismissOpacity = 0
+      this.playDismissProxySize = target.circleDiameter
+      this.playDismissProxyOpacity = 1
+      this.getUIContext()?.animateTo({
+        duration: this.playDismissDotDuration,
+        curve: Curve.EaseIn
+      }, () => {
+        this.playDismissProxySize = target.dotDiameter
+        this.playDismissProxyOpacity = 0
+      })
+      this.playDismissTimer = setTimeout(() => {
+        this.playDismissTimer = -1
+        this.isShowPlay = false
+        this.isShowCoverScaleGuide = false
+      }, this.playDismissDotDuration + 16)
+    }, this.playDismissContentDuration + 16)
   }
 
   setShowPlayFalse(){
@@ -12274,27 +12322,63 @@ export struct LocalMusic {
     .animation({ curve: Curve.Sharp, duration: 300 })
   }
 
+  @Builder
+  private MusicPlayDismissProxyDot() {
+    Stack({ alignContent: Alignment.Center }) {
+      Image(StrUtil.isNotEmpty(this.cover) ? this.cover as string : $r('app.media.alt'))
+        .width('100%')
+        .height('100%')
+        .objectFit(ImageFit.Cover)
+        .alt($r('app.media.alt'))
+    }
+    .width(this.playDismissProxySize)
+    .height(this.playDismissProxySize)
+    .borderRadius(this.playDismissProxySize)
+    .clip(true)
+    .opacity(this.playDismissProxyOpacity)
+    .translate({ x: this.playDismissTranslateX, y: this.translateY })
+    .shadow({
+      radius: 18,
+      type: ShadowType.BLUR,
+      color: 'on_primary'
+    })
+  }
+
   @Builder
   MusicPlayBuilder() {
-    Column() {
-      this.IjkMusicPlayerView()
-    }
-    .visualEffect(deviceInfo.sdkApiVersion>=20&&this.bgController?
-      new hdsEffect.HdsEffectBuilder()
-        .shaderEffect({
-          effectType: hdsEffect.EffectType.UV_BACKGROUND_FLOW_LIGHT,
-          animation: {
-            duration: 10000,
-            iterations: -1,
-            autoPlay: true,
-            onFinish: ()=> {
-              console.info('Succeeded in finishing');
-            }
-          },
-          controller: this.bgController,
-        })
-        .buildEffect():null)
+    Stack({ alignContent: Alignment.Center }) {
+      Column() {
+        this.IjkMusicPlayerView()
+      }
+      .visualEffect(deviceInfo.sdkApiVersion>=20&&this.bgController&&this.playDismissOpacity>=1
+        && this.playDismissProxySize<=0 && this.playDismissBorderRadius<=0 ?
+        new hdsEffect.HdsEffectBuilder()
+          .shaderEffect({
+            effectType: hdsEffect.EffectType.UV_BACKGROUND_FLOW_LIGHT,
+            animation: {
+              duration: 10000,
+              iterations: -1,
+              autoPlay: true,
+              onFinish: ()=> {
+                console.info('Succeeded in finishing');
+              }
+            },
+            controller: this.bgController,
+          })
+          .buildEffect():null)
+
+      .height('100%')
+      .width('100%')
+      .borderRadius(this.playDismissBorderRadius)
+      .clip(true)
+      .translate({ x: this.playDismissTranslateX, y: this.translateY })
+      .scale({ x: this.playDismissScale, y: this.playDismissScaleY })
+      .opacity(this.playDismissOpacity)
 
+      if (this.playDismissProxySize > 0) {
+        this.MusicPlayDismissProxyDot()
+      }
+    }
     .height('100%')
     .width('100%')
     .onAppear(() => {
@@ -12303,9 +12387,6 @@ export struct LocalMusic {
     .onDisAppear(() => {
       this.resetMusicPlayDismissState()
     })
-    .translate({ x: this.playDismissTranslateX, y: this.translateY })
-    .scale({ x: this.playDismissScale, y: this.playDismissScale })
-    .opacity(this.playDismissOpacity)
     .gesture(
       PanGesture(this.panOption)
         .onActionUpdate((event?: GestureEvent) => {
@@ -12332,7 +12413,7 @@ export struct LocalMusic {
                 duration: 500,
                 curve: Curve.Sharp
               }, () => {
-                this.scaleValueImage = Math.min(1, Math.max(0.5, 1 - this.translateY / 880));
+                this.scaleValueImage = Math.min(1, Math.max(0.4, 1 - this.translateY / 400));
                 console.info('onecold scaleValueImage:', this.scaleValueImage)
                 this.scaleValueText = Math.min(1, Math.max(0.88, 1 - this.translateY / 2000));
                 this.playDragUiOpacity = Math.min(1, Math.max(0, 1 - this.translateY / 300));
@@ -14316,7 +14397,6 @@ export struct LocalMusic {
         .alt($r('app.media.alt'))
         .margin({ right: 8, left: 8, top: 5 })
         .aspectRatio(1)
-        .geometryTransition('cover') // 绑定标识符
         .opacity(this.opacityValueImage)
         .clickEffect({ level: ClickEffectLevel.MIDDLE,scale:0.8 })
         .bindContextMenu(this.MenuImageBuilder(this.cover), ResponseType.LongPress,
@@ -14332,7 +14412,6 @@ export struct LocalMusic {
         .visibility(this.isPuraWP() ? Visibility.None : Visibility.Visible)
         .borderRadius(this.isCoverRectangle ? 20 : '100%')
         .clip(true)
-
         .animation({
           duration: 1000,  // 与 setInterval 同步
           curve: Curve.Linear,