|
151 | 151 | /> |
152 | 152 | </div> |
153 | 153 | </div> |
154 | | - <div class="lyric-main"> |
155 | | - <PlayerLyric /> |
156 | | - </div> |
| 154 | + <div class="lyric-main" /> |
157 | 155 | </div> |
158 | 156 | </div> |
159 | 157 |
|
| 158 | + <!-- 独立歌词覆盖层(提取到 mobile-content 之外以避免 transform stacking context 阻断 mix-blend-mode) --> |
| 159 | + <div |
| 160 | + v-if="hasLyric" |
| 161 | + class="lyric-overlay" |
| 162 | + :class="{ swiping: isSwiping }" |
| 163 | + :style="{ transform: lyricPageTransform }" |
| 164 | + > |
| 165 | + <PlayerLyric /> |
| 166 | + </div> |
| 167 | + |
160 | 168 | <!-- 页面指示器 --> |
161 | 169 | <div class="pagination" v-if="hasLyric"> |
162 | 170 | <div |
@@ -230,6 +238,23 @@ const { direction, isSwiping, lengthX } = useSwipe(mobileStart, { |
230 | 238 | }, |
231 | 239 | }); |
232 | 240 |
|
| 241 | +// 计算歌词覆盖层的位移(与 mobile-content 内歌词页视觉同步,但在 stacking context 之外) |
| 242 | +const lyricPageTransform = computed(() => { |
| 243 | + // pageIndex=0 时覆盖层在屏幕右侧,pageIndex=1 时回到屏幕内 |
| 244 | + const baseOffset = (1 - pageIndex.value) * 100; |
| 245 | + if (!isSwiping.value || !hasLyric.value) { |
| 246 | + return `translateX(${baseOffset}%)`; |
| 247 | + } |
| 248 | + let pixelOffset = lengthX.value; |
| 249 | + if (pageIndex.value === 0 && pixelOffset < 0) { |
| 250 | + pixelOffset = pixelOffset * 0.3; |
| 251 | + } |
| 252 | + if (pageIndex.value === 1 && pixelOffset > 0) { |
| 253 | + pixelOffset = pixelOffset * 0.3; |
| 254 | + } |
| 255 | + return `translateX(calc(${baseOffset}% - ${pixelOffset}px))`; |
| 256 | +}); |
| 257 | +
|
233 | 258 | // 计算实时的变换位置 |
234 | 259 | const contentTransform = computed(() => { |
235 | 260 | const baseOffset = pageIndex.value * 50; // 百分比 |
@@ -536,6 +561,22 @@ const contentTransform = computed(() => { |
536 | 561 | } |
537 | 562 | } |
538 | 563 | } |
| 564 | + // 歌词覆盖层:提取到 mobile-content 之外,使 mix-blend-mode 能与实际模糊背景混合 |
| 565 | + .lyric-overlay { |
| 566 | + position: absolute; |
| 567 | + top: 0; |
| 568 | + left: 0; |
| 569 | + width: 100%; |
| 570 | + height: 100%; |
| 571 | + // 顶部留出 lyric-page padding-top(60px) + lyric-header 高度(约 80px) |
| 572 | + padding: 140px 24px 0; |
| 573 | + box-sizing: border-box; |
| 574 | + mix-blend-mode: var(--lyric-blend-mode); |
| 575 | + transition: transform 0.3s cubic-bezier(0.25, 1, 0.5, 1); |
| 576 | + &.swiping { |
| 577 | + transition: none; |
| 578 | + } |
| 579 | + } |
539 | 580 | .pagination { |
540 | 581 | position: absolute; |
541 | 582 | bottom: 24px; |
|
0 commit comments