Stop the kitten measuring the size it shrank itself to
The mascot shrinks a step when it yields to a card, and the overlap test read getBoundingClientRect, which reports the scaled box. So a card resting at the mascot's edge drove a loop: overlap, shrink, no overlap, grow, overlap again, every poll tick. Measure the layout box instead — centre plus offsetWidth/offsetHeight, which the yield transform doesn't move. Hysteresis would have hidden the pulsing; this removes the path that caused it. Claude-Session: https://claude.ai/code/session_01GJHNvirh7Hzhc9RL3HAvz7
This commit is contained in:
@@ -24,6 +24,21 @@ export interface CardOverlap {
|
||||
modal: boolean
|
||||
}
|
||||
|
||||
// The mascot shrinks a step when it yields (.petal-companion-faded), and
|
||||
// getBoundingClientRect reports the *scaled* box. Measuring that lets the
|
||||
// mascot shrink out of its own overlap test: it yields, stops overlapping,
|
||||
// wakes back up, overlaps again — pulsing forever against a card that sits just
|
||||
// at its edge. The layout box doesn't move when it yields, so measure that. The
|
||||
// transform origin is the centre, so it's the visual centre ± the layout size.
|
||||
function layoutRect(el: HTMLElement) {
|
||||
const r = el.getBoundingClientRect()
|
||||
const halfW = el.offsetWidth / 2
|
||||
const halfH = el.offsetHeight / 2
|
||||
const cx = (r.left + r.right) / 2
|
||||
const cy = (r.top + r.bottom) / 2
|
||||
return { left: cx - halfW, right: cx + halfW, top: cy - halfH, bottom: cy + halfH }
|
||||
}
|
||||
|
||||
// Reports what, if anything, the mascot should yield to at the given element.
|
||||
// Used to fade the corner mascot out of the way when a card or panel reaches
|
||||
// into its corner, so nothing is ever hidden (or made unclickable) by the
|
||||
@@ -37,7 +52,7 @@ export function useCardOverlap(ref: RefObject<HTMLElement | null>): CardOverlap
|
||||
const check = () => {
|
||||
const el = ref.current
|
||||
if (!el) return
|
||||
const r = el.getBoundingClientRect()
|
||||
const r = layoutRect(el)
|
||||
const hits = (selector: string) => {
|
||||
for (const other of document.querySelectorAll(selector)) {
|
||||
const b = other.getBoundingClientRect()
|
||||
|
||||
Reference in New Issue
Block a user