From c2e80ab6906cff0372975fa0846a5686f621276a Mon Sep 17 00:00:00 2001 From: Pihkaal Date: Wed, 14 Jan 2026 15:09:09 +0100 Subject: [PATCH] feat(buttonNavigation): block any interactions while the selector is being animated --- app/composables/useButtonNavigation.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/app/composables/useButtonNavigation.ts b/app/composables/useButtonNavigation.ts index 0c77738..55804b6 100644 --- a/app/composables/useButtonNavigation.ts +++ b/app/composables/useButtonNavigation.ts @@ -1,5 +1,7 @@ import gsap from "gsap"; +const SELECTOR_SPEED = 500; + export const useButtonNavigation = >({ buttons, initialButton, @@ -29,6 +31,11 @@ export const useButtonNavigation = >({ const selectedButton = ref(initialButton); const selectorPosition = ref(buttons[initialButton]!); const nextButton = ref(); + const isAnimating = ref(false); + + const blockInteractions = computed( + () => confirmationModal.isOpen || disabled?.value || isAnimating.value, + ); const getNavigationTarget = ( value: Entry | [buttonName: Entry, blocked: boolean] | undefined, @@ -149,10 +156,14 @@ export const useButtonNavigation = >({ }; const animateToButton = (targetButton: Entry, path?: Array | null) => { - const SPEED = 400; const pathButtons = path && path.length > 0 ? path : [targetButton]; - const timeline = gsap.timeline(); + isAnimating.value = true; + const timeline = gsap.timeline({ + onComplete: () => { + isAnimating.value = false; + }, + }); let prevRect = selectorPosition.value; selectorPosition.value = [...selectorPosition.value]; @@ -160,7 +171,7 @@ export const useButtonNavigation = >({ for (const button of pathButtons) { const buttonRect = buttons[button]!; const distance = calculateDistance(prevRect, buttonRect); - const duration = distance / SPEED; + const duration = distance / SELECTOR_SPEED; timeline.to( selectorPosition.value, @@ -184,7 +195,7 @@ export const useButtonNavigation = >({ const { onClick } = useScreen(); onClick((x: number, y: number) => { - if (confirmationModal.isOpen || disabled?.value) return; + if (blockInteractions.value) return; for (const [buttonName, buttonRect] of Object.entries(buttons) as [ Entry, @@ -214,7 +225,7 @@ export const useButtonNavigation = >({ }); useKeyDown((key) => { - if (confirmationModal.isOpen || disabled?.value) return; + if (blockInteractions.value) return; const currentButton = selectedButton.value as Entry; const currentNav = navigation[currentButton];