fix(cp活动): 修复苹果端奖励滚动动画闪烁问题

This commit is contained in:
hzj 2026-05-07 18:49:08 +08:00
parent fa16aef96c
commit 6cc3dd2a85

View File

@ -261,7 +261,7 @@
<div class="reward-wrapper"> <div class="reward-wrapper">
<div ref="rewardViewportRef" class="reward-scroll-viewport"> <div ref="rewardViewportRef" class="reward-scroll-viewport">
<!-- 滚动容器 --> <!-- 滚动容器 -->
<div v-if="rewardList.length" class="scroll-wrapper"> <div v-if="rewardList.length" ref="rewardScrollRef" class="scroll-wrapper">
<!-- 3套内容减少 iOS WebView 动画循环边界闪烁 --> <!-- 3套内容减少 iOS WebView 动画循环边界闪烁 -->
<div class="scroll-content" v-for="value in 3" :key="value"> <div class="scroll-content" v-for="value in 3" :key="value">
<div <div
@ -353,6 +353,7 @@ const props = defineProps({
}) })
const rewardViewportRef = ref(null) const rewardViewportRef = ref(null)
const rewardScrollRef = ref(null)
const rewardList = computed(() => { const rewardList = computed(() => {
return Array.isArray(props.rewards?.activityRewardProps) ? props.rewards.activityRewardProps : [] return Array.isArray(props.rewards?.activityRewardProps) ? props.rewards.activityRewardProps : []
@ -385,7 +386,7 @@ let rewardRestartTimer = null
let rewardAnimationFrame = null let rewardAnimationFrame = null
let rewardLastFrameTime = 0 let rewardLastFrameTime = 0
let rewardLoopDistance = 0 let rewardLoopDistance = 0
let rewardScrollPosition = 0 let rewardTranslatePosition = 0
const waitForLayoutFrame = () => { const waitForLayoutFrame = () => {
return new Promise((resolve) => { return new Promise((resolve) => {
@ -414,12 +415,13 @@ const restartRewardScroll = async () => {
rewardRestartTimer = setTimeout(async () => { rewardRestartTimer = setTimeout(async () => {
await waitForLayoutFrame() await waitForLayoutFrame()
const viewport = rewardViewportRef.value const viewport = rewardViewportRef.value
if (!viewport || !rewardList.value.length) { const scrollWrapper = rewardScrollRef.value
if (!viewport || !scrollWrapper || !rewardList.value.length) {
rewardRestartTimer = null rewardRestartTimer = null
return return
} }
const scrollCopies = viewport.querySelectorAll('.scroll-content') const scrollCopies = scrollWrapper.querySelectorAll('.scroll-content')
if (scrollCopies.length < 2) { if (scrollCopies.length < 2) {
rewardRestartTimer = null rewardRestartTimer = null
return return
@ -434,21 +436,22 @@ const restartRewardScroll = async () => {
return return
} }
rewardScrollPosition = 0 rewardTranslatePosition = 0
viewport.scrollLeft = 0 viewport.scrollLeft = 0
scrollWrapper.style.transform = 'translate3d(0, 0, 0)'
rewardLastFrameTime = performance.now() rewardLastFrameTime = performance.now()
const step = (now) => { const step = (now) => {
const elapsed = now - rewardLastFrameTime const elapsed = now - rewardLastFrameTime
rewardLastFrameTime = now rewardLastFrameTime = now
const distancePerMs = rewardLoopDistance / 8000 const distancePerMs = rewardLoopDistance / 8000
rewardScrollPosition += distancePerMs * elapsed rewardTranslatePosition += distancePerMs * elapsed
if (rewardScrollPosition >= rewardLoopDistance) { if (rewardTranslatePosition >= rewardLoopDistance) {
rewardScrollPosition -= rewardLoopDistance rewardTranslatePosition -= rewardLoopDistance
} }
viewport.scrollLeft = rewardScrollPosition scrollWrapper.style.transform = `translate3d(${-rewardTranslatePosition}px, 0, 0)`
rewardAnimationFrame = requestAnimationFrame(step) rewardAnimationFrame = requestAnimationFrame(step)
} }
@ -478,6 +481,9 @@ onUnmounted(() => {
cancelAnimationFrame(rewardAnimationFrame) cancelAnimationFrame(rewardAnimationFrame)
rewardAnimationFrame = null rewardAnimationFrame = null
} }
if (rewardScrollRef.value) {
rewardScrollRef.value.style.transform = ''
}
}) })
</script> </script>
@ -521,13 +527,17 @@ onUnmounted(() => {
align-items: center; align-items: center;
overflow: hidden; overflow: hidden;
direction: ltr; direction: ltr;
scroll-behavior: auto;
overflow-anchor: none; overflow-anchor: none;
} }
.scroll-wrapper { .scroll-wrapper {
display: flex; display: flex;
width: fit-content; width: fit-content;
transform: translate3d(0, 0, 0);
-webkit-transform: translate3d(0, 0, 0);
backface-visibility: hidden;
-webkit-backface-visibility: hidden;
will-change: transform;
} }
.scroll-content { .scroll-content {