Repository navigation
Expand file tree
/
Copy pathindex.ts
More file actions
130 lines (111 loc) · 3.51 KB
/
Copy pathindex.ts
File metadata and controls
130 lines (111 loc) · 3.51 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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
import { debounce } from 'lodash';
import { MIN_DEVICE_PIXEL_RATIO } from '../../common/constant/options';
import type { SpreadSheet } from '../../sheet-type';
import { isMobile } from '../../utils/is-mobile';
export class HdAdapter {
private viewport = window as typeof window & { visualViewport: Element };
private devicePixelRatioMedia: MediaQueryList;
private spreadsheet: SpreadSheet;
private isDevicePixelRatioChange = false;
constructor(spreadsheet: SpreadSheet) {
this.spreadsheet = spreadsheet;
}
public init = () => {
this.initDevicePixelRatioListener();
this.initDeviceZoomListener();
};
public destroy = () => {
this.removeDevicePixelRatioListener();
this.removeDeviceZoomListener();
};
private initDevicePixelRatioListener() {
this.devicePixelRatioMedia = window.matchMedia(
`(resolution: ${window.devicePixelRatio}dppx)`,
);
if (this.devicePixelRatioMedia?.addEventListener) {
this.devicePixelRatioMedia.addEventListener(
'change',
this.renderByDevicePixelRatioChanged,
);
} else {
this.devicePixelRatioMedia.addListener(
this.renderByDevicePixelRatioChanged,
);
}
}
private removeDevicePixelRatioListener = () => {
if (this.devicePixelRatioMedia?.removeEventListener) {
this.devicePixelRatioMedia.removeEventListener(
'change',
this.renderByDevicePixelRatioChanged,
);
} else {
this.devicePixelRatioMedia.removeListener(
this.renderByDevicePixelRatioChanged,
);
}
};
private initDeviceZoomListener = () => {
if (isMobile()) {
return;
}
// VisualViewport support browser zoom & mac touch tablet
this.viewport?.visualViewport?.addEventListener(
'resize',
this.renderByZoomScaleWithoutResizeEffect,
);
};
private removeDeviceZoomListener = () => {
if (isMobile()) {
return;
}
this.viewport?.visualViewport?.removeEventListener(
'resize',
this.renderByZoomScaleWithoutResizeEffect,
);
};
/**
* DPR 改变也会触发 visualViewport 的 resize 事件, 预期是只监听双指缩放, 所以这里规避掉
* @see https://github.com/antvis/S2/issues/2072
*/
private renderByZoomScaleWithoutResizeEffect = (
event: Event & { target: VisualViewport },
) => {
this.isDevicePixelRatioChange = false;
this.renderByZoomScale(event);
};
private renderByDevicePixelRatioChanged = () => {
this.isDevicePixelRatioChange = true;
this.renderByDevicePixelRatio();
};
private renderByDevicePixelRatio = (ratio = window.devicePixelRatio) => {
const {
container,
options: { width, height, devicePixelRatio },
} = this.spreadsheet;
const canvas = this.spreadsheet.getCanvasElement();
const lastRatio = container.get('pixelRatio');
if (lastRatio === ratio || !canvas) {
return;
}
// 缩放时, 以向上取整后的缩放比为准
// 设备像素比改变时, 取当前和用户配置中最大的, 保证显示效果
const pixelRatio = Math.max(
ratio,
devicePixelRatio,
MIN_DEVICE_PIXEL_RATIO,
);
container.set('pixelRatio', pixelRatio);
container.changeSize(width, height);
this.spreadsheet.render(false);
};
private renderByZoomScale = debounce(
(event: Event & { target: VisualViewport }) => {
const ratio = Math.ceil(event.target.scale);
if (ratio >= 1 && !this.isDevicePixelRatioChange) {
this.renderByDevicePixelRatio(ratio);
}
},
350,
);
}