Skip to content

fix: recalculate spotlight overlay position on scroll#920

Open
Niteshagarwal01 wants to merge 1 commit into
magic-peach:mainfrom
Niteshagarwal01:main
Open

fix: recalculate spotlight overlay position on scroll#920
Niteshagarwal01 wants to merge 1 commit into
magic-peach:mainfrom
Niteshagarwal01:main

Conversation

@Niteshagarwal01
Copy link
Copy Markdown

@Niteshagarwal01 Niteshagarwal01 commented May 22, 2026

🛠 Fix: Recalculate Spotlight Overlay Position on Scroll and Resize #913

📝 Description

This PR resolves a visual regression within the OnboardingTour component where the spotlight overlay (<Spotlight />) detaches from its targeted DOM element when the user scrolls or resizes the viewport.

🐛 The Bug

During the onboarding flow, the highlighted spotlight rectangle uses absolute coordinates computed via getBoundingClientRect() at the exact moment a tour step is initialized.

  1. Scroll Detachment: Because the <svg> overlay uses a fixed inset positioning layout, scrolling the page causes the underlying target element to shift relative to the viewport while the SVG mask remains stationary. This results in the spotlight illuminating unrelated content.
  2. Aggressive Refocusing: The original resize handler directly triggered the measureTarget function. Because measureTarget uses scrollIntoView({ behavior: "smooth" }) to ensure the targeted element is visible, any window resize implicitly forced the browser to hijack the user's scroll position, resulting in a jarring UX.

💡 The Solution

This PR decouples the "scrolling into view" logic from the coordinate recalculation logic, ensuring the spotlight dynamically tracks its target frame by frame without coercively scrolling the page.

Key Changes:

  1. Separation of Concerns (updatePosition)
    Introduced a pure updatePosition callback that safely retrieves the active target element (document.getElementById) and updates the targetRect state purely using getBoundingClientRect() without any side effects.

  2. Capture-Phase Scroll Listener
    Added a scroll event listener to the window. Crucially, this listener is attached with useCapture: true (window.addEventListener("scroll", handler, true)). Since scroll events on inner overflow containers do not bubble up to the window, the capturing phase is required to ensure we detect scrolling occurring within any nested scrollable area.

  3. Performance Optimization (requestAnimationFrame)
    Scroll and resize events can fire at extremely high frequencies. To prevent layout thrashing and state-update bottlenecks, the handleUpdate event handler wraps updatePosition inside requestAnimationFrame. Existing frames are cleanly cancelled to guarantee the recalculation strictly binds to the browser's native rendering cycle.

  4. Refactored useEffect Teardown
    Ensured no memory leaks by securely cleaning up both the scroll (with matching useCapture boolean) and resize event listeners alongside canceling any lingering animation frames on component unmount.


📸 Expected Behavior

  • Scrolling: When the onboarding tour is active, scrolling up or down smoothly drags the spotlight mask alongside the intended UI component.
  • Resizing: Resizing the browser window seamlessly recalculates the spotlight dimensions in real-time. The window will no longer aggressively attempt to scroll the element into the center of the viewport during the resize drag.

🧪 Steps to Test

  1. Navigate to the app and trigger the onboarding/tutorial flow (ensure localStorage key reframe_onboarding_complete is cleared).
  2. Wait for the spotlight overlay to appear.
  3. Scroll the page vertically/horizontally. Verify that the spotlight strictly tracks the highlighted UI component.
  4. Resize the browser window horizontally. Verify that the highlight accurately conforms to the new component dimensions without forcing a sudden scrollIntoView jump.

Closes #913

@vercel
Copy link
Copy Markdown

vercel Bot commented May 22, 2026

@Niteshagarwal01 is attempting to deploy a commit to the magic-peach1's projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link
Copy Markdown
Contributor

👋 Thanks for your PR, @Niteshagarwal01!

Welcome to Reframe — a browser-based video editor built for everyone 🎬

What happens next

  1. 🤖 Automated checks — build & TypeScript typecheck will run automatically
  2. Vercel preview — a preview deployment will be created (requires maintainer authorization for fork PRs)
  3. 👀 Code review — a maintainer will review your changes
  4. 🚀 Merge — once approved, your PR will be merged!

Quick checklist

  • PR title follows Conventional Commits (e.g. feat: add dark mode)
  • Linked the issue this PR closes (e.g. Closes #123)
  • Tested the changes locally (bun run dev)
  • Build passes (bun run build)

Useful links

Happy coding! 🎉

@github-actions github-actions Bot added level:beginner Beginner level - 20 pts type:bug Bug fix type:design UI/UX design type:performance Performance type:testing Testing labels May 22, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

✅ PR Format Check Passed — @Niteshagarwal01

Basic format checks passed. A maintainer will review your code changes.

This does not mean the PR is approved — it just means the format is correct.

@Niteshagarwal01
Copy link
Copy Markdown
Author

@magic-peach kindly review it and merge it if its ok to you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

level:beginner Beginner level - 20 pts type:bug Bug fix type:design UI/UX design type:performance Performance type:testing Testing

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG]: Tutorial spotlight overlay moves incorrectly while scrolling

1 participant