Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | import type { NumberLineState, RenderConstant } from '../types' import { numberToScreenX } from '../numberLineTicks' import type { MathConstant } from './constantsData' export interface ConstantVisibility { constant: MathConstant screenX: number isOnScreen: boolean opacity: number } /** * Compute visibility for a single constant. * * A constant is visible when: * 1. It's on screen (within canvas bounds + margin) * 2. The zoom level is adequate to distinguish it (pxPerPrecisionUnit >= 20) * * Unlike FindTheNumber, there's no position proximity factor — * constants appear whenever on screen AND zoomed enough. */ export function computeConstantVisibility( constant: MathConstant, state: NumberLineState, canvasWidth: number ): ConstantVisibility { const screenX = numberToScreenX(constant.value, state.center, state.pixelsPerUnit, canvasWidth) // Margin so constants don't pop in right at the edge const margin = 40 const isOnScreen = screenX >= -margin && screenX <= canvasWidth + margin if (!isOnScreen) { return { constant, screenX, isOnScreen, opacity: 0 } } // Zoom adequacy: one unit at the constant's precision should be >= 20px const unitAtPrecision = 10 ** -constant.revealPrecision const pxPerPrecisionUnit = unitAtPrecision * state.pixelsPerUnit const opacity = Math.min(1, pxPerPrecisionUnit / 20) return { constant, screenX, isOnScreen, opacity } } /** * Compute visibility for all constants at once. * Returns only those with opacity > 0. */ export function computeAllConstantVisibilities( constants: MathConstant[], state: NumberLineState, canvasWidth: number, discoveredSet: Set<string> ): RenderConstant[] { const result: RenderConstant[] = [] for (const constant of constants) { const vis = computeConstantVisibility(constant, state, canvasWidth) if (vis.opacity > 0) { result.push({ id: constant.id, symbol: constant.symbol, screenX: vis.screenX, opacity: vis.opacity, discovered: discoveredSet.has(constant.id), }) } } return result } |