-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinitialPanZoom.ts
More file actions
97 lines (90 loc) · 2.98 KB
/
initialPanZoom.ts
File metadata and controls
97 lines (90 loc) · 2.98 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import type { Draft } from 'immer';
import type { Size } from '../../types/utils.js';
import { assertUnreachable } from '../../utilities/assert.js';
import type { ReactRoiState } from '../roiReducer.js';
// Initial values are set to 1 and not 0 to avoid division by 0
export const initialSize: Size = {
width: 1,
height: 1,
};
/**
* Updates the base transform which places the target relative to the container.
* This should only be called once both the target and container sizes are known.
*/
export function updateBasePanZoom(draft: Draft<ReactRoiState>) {
switch (draft.resizeStrategy) {
case 'contain':
updateBasePanZoomContain(draft);
break;
case 'cover':
updateBasePanZoomCover(draft);
break;
case 'center':
updateBasePanZoomCenter(draft);
break;
case 'none':
updateInitialPanZoomNone(draft);
break;
default:
assertUnreachable(draft.resizeStrategy);
}
}
function updateBasePanZoomCover(draft: Draft<ReactRoiState>) {
const { targetSize, containerSize } = draft;
const wFactor = targetSize.width / containerSize.width;
const hFactor = targetSize.height / containerSize.height;
if (wFactor > 1 || hFactor > 1) {
// Target is bigger than container
if (wFactor > hFactor) {
// Target is wider than container
draft.basePanZoom.scale = 1 / hFactor;
draft.basePanZoom.translation = [
-(targetSize.width / hFactor - containerSize.width) / 2,
0,
];
} else {
// Target is taller than container
draft.basePanZoom.scale = 1 / wFactor;
draft.basePanZoom.translation = [
0,
-(targetSize.height / wFactor - containerSize.height) / 2,
];
}
} else {
// The image is smaller, just center it
draft.basePanZoom.scale = 1;
updateBasePanZoomCenter(draft);
}
}
function updateBasePanZoomContain(draft: Draft<ReactRoiState>) {
const { targetSize, containerSize } = draft;
const wFactor = targetSize.width / containerSize.width;
const hFactor = targetSize.height / containerSize.height;
if (wFactor > 1 || hFactor > 1) {
// Target is bigger than the container
if (wFactor > hFactor) {
// Target is wider than the container
draft.basePanZoom.scale = 1 / wFactor;
updateBasePanZoomCenter(draft);
} else {
// Target is taller than the container
draft.basePanZoom.scale = 1 / hFactor;
updateBasePanZoomCenter(draft);
}
} else {
// The image is smaller, just center it
draft.basePanZoom.scale = 1;
updateBasePanZoomCenter(draft);
}
}
function updateBasePanZoomCenter(draft: Draft<ReactRoiState>) {
const { targetSize, containerSize, basePanZoom } = draft;
draft.basePanZoom.translation = [
(containerSize.width - basePanZoom.scale * targetSize.width) / 2,
(containerSize.height - basePanZoom.scale * targetSize.height) / 2,
];
}
function updateInitialPanZoomNone(draft: Draft<ReactRoiState>) {
draft.basePanZoom.scale = 1;
draft.basePanZoom.translation = [0, 0];
}