Skip to content

scroll: ease scrollToAnchor (quadratic) and preserve horizontal scroll position #121

@yigitdot

Description

@yigitdot

From Gemini's review of PR #118.

Background

lib/scroll.ts scrollToAnchor animates with linear easing and hard-codes window.scrollTo(0, …) (X = 0):

const tick = (now: number) => {
  const t = Math.min(1, (now - startTime) / duration);
  window.scrollTo(0, startY + distance * t);
  ...

Gemini's suggestion:

const ease = t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;
window.scrollTo(window.scrollX, startY + distance * ease);

Linear feels mechanical vs the browser's native eased curve; hard-coding X = 0 would yank horizontal scroll to the left edge if the page is ever horizontally scrolled.

Why this is its own issue, not part of #118

scrollToAnchor was moved byte-identical from MobileMenu.tsx into lib/scroll.ts in #118. Changing its easing / axis behavior inside a pure move-refactor would obscure the diff and is unrelated to the #116 hash-accumulation fix. Filed standalone so the move stays clean and the behavior change is reviewed on its own merits.

Scope

  • Quadratic (or similar) ease-in-out for the rAF tick.
  • Use window.scrollX instead of literal 0.
  • Re-verify the reduced-motion early-return and the single-flight cancel/restore path still hold.
  • Only the mobile drawer calls scrollToAnchor today (desktop nav uses native scrollIntoView), so the blast radius is the drawer's close-then-scroll animation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions