src/render-size.ts (1265 bytes)
1 // The width of the canvas of a page, in device pixels. Pure: no DOM. 2 3 /** The widest canvas. */ 4 export const MAX_RENDER_WIDTH = 4096; 5 6 /** 7 * The largest canvas, in pixels: about 48 MB of RGBA. A larger canvas can 8 * fail to draw, or take the memory of the WebView on a phone. 9 */ 10 export const MAX_RENDER_AREA = 12_000_000; 11 12 /** The narrowest canvas. */ 13 export const MIN_RENDER_WIDTH = 300; 14 15 export interface RenderInput { 16 /** The width of the page on the screen, in CSS pixels. */ 17 cssWidth: number; 18 /** Device pixels per CSS pixel. */ 19 dpr: number; 20 /** The pinch zoom of the whole app (visualViewport.scale). 1 is no zoom. */ 21 zoom: number; 22 /** The height of the page divided by its width. */ 23 aspect: number; 24 } 25 26 /** 27 * The width of the canvas for a page: one canvas pixel for each device 28 * pixel at the pinch zoom, so the text is sharp also when the user zooms 29 * in. The width stays within MAX_RENDER_WIDTH and MAX_RENDER_AREA, and is 30 * at least MIN_RENDER_WIDTH. 31 */ 32 export function renderWidth(s: RenderInput): number { 33 const sharp = s.cssWidth * s.dpr * Math.max(1, s.zoom); 34 const byArea = Math.sqrt(MAX_RENDER_AREA / Math.max(s.aspect, 0.01)); 35 return Math.round(Math.max(MIN_RENDER_WIDTH, Math.min(sharp, MAX_RENDER_WIDTH, byArea))); 36 }