( bounds: Bounds, canvasWidth: number, canvasHeight: number, padding = 80, )
| 79 | |
| 80 | /** Compute viewport that fits the given bounds into a canvas of (w, h). */ |
| 81 | export function fitBounds( |
| 82 | bounds: Bounds, |
| 83 | canvasWidth: number, |
| 84 | canvasHeight: number, |
| 85 | padding = 80, |
| 86 | ): Viewport { |
| 87 | const bw = bounds.maxX - bounds.minX || 1; |
| 88 | const bh = bounds.maxY - bounds.minY || 1; |
| 89 | const scale = Math.min( |
| 90 | (canvasWidth - padding * 2) / bw, |
| 91 | (canvasHeight - padding * 2) / bh, |
| 92 | ); |
| 93 | const cx = (bounds.minX + bounds.maxX) / 2; |
| 94 | const cy = (bounds.minY + bounds.maxY) / 2; |
| 95 | return { |
| 96 | x: canvasWidth / 2 - cx * scale, |
| 97 | y: canvasHeight / 2 - cy * scale, |
| 98 | scale, |
| 99 | }; |
| 100 | } |
| 101 | |
| 102 | /** Smoothly animate from one viewport to another. Returns a cancel function. */ |
| 103 | export function animateViewport( |
no outgoing calls
no test coverage detected