src/scroll.ts (1048 bytes)
1 // Where a scroll box scrolls to show a mark. Pure: no DOM. 2 3 /** The share of the view height above the mark after a scroll. The mark lands in the upper third. */ 4 export const LEAD = 0.25; 5 6 /** A vertical extent, in the scroll space of the box: 0 is the top of its content. */ 7 export interface Extent { 8 top: number; 9 bottom: number; 10 } 11 12 /** 13 * The scroll position that shows `mark`, or null when the mark is in view 14 * already. The view shows `height` pixels from the scroll position `top`. 15 * `max` is the largest scroll position. The mark goes LEAD of the height 16 * below the top of the view, so the lines after it show too. With 17 * `always`, there is a position also for a mark in view. 18 */ 19 export function scrollTarget( 20 mark: Extent, 21 view: { top: number; height: number }, 22 max: number, 23 always = false, 24 ): number | null { 25 const inView = mark.top >= view.top && mark.bottom <= view.top + view.height; 26 if (inView && !always) return null; 27 return Math.round(Math.min(Math.max(0, mark.top - view.height * LEAD), Math.max(0, max))); 28 }