Line data Source code
1 : /** The padding between the viewport and the fitted plan */
2 : export const PROFILE_FIT_PADDING = 24;
3 : /** The padding at the bottom of the viewport, which also clears the controls in the bottom corners */
4 : export const PROFILE_FIT_PADDING_BOTTOM = 44;
5 :
6 : /** The bounds of the drawn plan in scene coordinates */
7 : export interface ProfileFitBounds {
8 : left: number;
9 : top: number;
10 : width: number;
11 : height: number;
12 : }
13 :
14 : export interface ProfileFitTransform {
15 : x: number;
16 : y: number;
17 : scale: number;
18 : }
19 :
20 : /**
21 : * Compute the transform that shows a plan as a whole in a viewport.
22 : *
23 : * The bounds are those of the drawn plan, which need not start at the origin of the scene. The plan is scaled down
24 : * until it fits (but never enlarged beyond scale 1) and centered in the space left by the paddings. Large plans
25 : * shrink as far as needed, zooming in is up to the user.
26 : */
27 1 : export function computeProfileFitTransform(
28 1 : bounds: ProfileFitBounds,
29 1 : viewportWidth: number,
30 1 : viewportHeight: number,
31 1 : ): ProfileFitTransform {
32 1 : const availableWidth = Math.max(1, viewportWidth - PROFILE_FIT_PADDING * 2);
33 1 : const availableHeight = Math.max(1, viewportHeight - PROFILE_FIT_PADDING - PROFILE_FIT_PADDING_BOTTOM);
34 1 : const scale = Math.min(1, availableWidth / bounds.width, availableHeight / bounds.height);
35 1 : return {
36 1 : x: PROFILE_FIT_PADDING + (availableWidth - bounds.width * scale) / 2 - bounds.left * scale,
37 1 : y: PROFILE_FIT_PADDING + (availableHeight - bounds.height * scale) / 2 - bounds.top * scale,
38 1 : scale,
39 1 : };
40 1 : }
|