From 816508888671200c696d15eb362ae99e3d4dd5a9 Mon Sep 17 00:00:00 2001 From: sugar Date: Sun, 2 Feb 2025 16:35:43 +0100 Subject: [PATCH 1/2] only run parallax effect when scrolling user profile running animation handler every frame is slow --- packages/frontend/src/pages/user/home.vue | 39 +++++++++++++++++------ 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/packages/frontend/src/pages/user/home.vue b/packages/frontend/src/pages/user/home.vue index 2cd06bb7b..ba6141bde 100644 --- a/packages/frontend/src/pages/user/home.vue +++ b/packages/frontend/src/pages/user/home.vue @@ -225,7 +225,7 @@ import MkTextarea from '@/components/MkTextarea.vue'; import MkOmit from '@/components/MkOmit.vue'; import MkInfo from '@/components/MkInfo.vue'; import MkButton from '@/components/MkButton.vue'; -import { getScrollPosition } from '@/scripts/scroll.js'; +import { getScrollContainer } from '@/scripts/scroll.js'; import { getUserMenu } from '@/scripts/get-user-menu.js'; import number from '@/filters/number.js'; import { userPage } from '@/filters/user.js'; @@ -282,6 +282,7 @@ const isEditingMemo = ref(false); const moderationNote = ref(props.user.moderationNote); const editModerationNote = ref(false); const movedFromLog = ref(null); +let scrollEl: null | HTMLElement = null; watch(moderationNote, async () => { await misskeyApi('admin/update-user-note', { userId: props.user.id, text: moderationNote.value }); @@ -313,15 +314,19 @@ async function fetchMovedFromLog() { } function parallaxLoop() { - parallaxAnimationId.value = window.requestAnimationFrame(parallaxLoop); + requestNextParallaxFrame(); parallax(); } +function requestNextParallaxFrame() { + parallaxAnimationId.value = window.requestAnimationFrame(parallaxLoop); +} + function parallax() { const banner = bannerEl.value as any; if (banner == null) return; - const top = getScrollPosition(rootEl.value); + const top = scrollEl?.scrollTop ?? scrollY; if (top < 0) return; @@ -330,6 +335,23 @@ function parallax() { banner.style.backgroundPosition = `center calc(50% - ${pos}px)`; } +function startParallax() { + (scrollEl ?? window).removeEventListener('scroll', startParallax); + requestNextParallaxFrame(); +} + +function addScrollEvent() { + (scrollEl ?? window).addEventListener('scroll', startParallax); +} + +function cancelParallax() { + if (parallaxAnimationId.value) { + window.cancelAnimationFrame(parallaxAnimationId.value); + parallaxAnimationId.value = null; + addScrollEvent(); + } +} + function showMemoTextarea() { isEditingMemo.value = true; nextTick(() => { @@ -394,7 +416,10 @@ watch([props.user], () => { }); onMounted(() => { - window.requestAnimationFrame(parallaxLoop); + scrollEl = getScrollContainer(rootEl.value); + addScrollEvent(); + (scrollEl ?? window).addEventListener('scrollend', cancelParallax); + parallax(); narrow.value = rootEl.value!.clientWidth < 1000; if (props.user.birthday) { @@ -417,11 +442,7 @@ onMounted(() => { }); }); -onUnmounted(() => { - if (parallaxAnimationId.value) { - window.cancelAnimationFrame(parallaxAnimationId.value); - } -}); +onUnmounted(cancelParallax);