Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 修复浏览器窗口多次放大后表格渲染模糊 close #2884 #2897

Merged
merged 1 commit into from
Sep 18, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 25 additions & 4 deletions packages/s2-core/src/ui/hd-adapter/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { debounce } from 'lodash';
import type { SpreadSheet } from '../../sheet-type';
import { isMobile } from '../../utils/is-mobile';

/**
* 基于 Canvas 的高清适配方案
* 1. 双屏切换, devicePixelRatio 变化时
* 2. Mac 触控板缩放
* 3. 浏览器窗口缩放
*/
export class HdAdapter {
private viewport = window as typeof window & {
visualViewport: VisualViewport;
Expand All @@ -13,6 +19,8 @@ export class HdAdapter {

private isDevicePixelRatioChange = false;

private zoomOffsetLeft: number | undefined;

constructor(spreadsheet: SpreadSheet) {
this.spreadsheet = spreadsheet;
}
Expand Down Expand Up @@ -91,6 +99,9 @@ export class HdAdapter {
await this.renderByZoomScale(event);
};

/**
* 如果是浏览器窗口的放大缩小 (command +/-), 也会触发
*/
private renderByDevicePixelRatioChanged = async () => {
this.isDevicePixelRatioChange = true;
await this.renderByDevicePixelRatio();
Expand All @@ -104,24 +115,34 @@ export class HdAdapter {
options: { width, height },
} = this.spreadsheet;
const canvas = this.spreadsheet.getCanvasElement();
const currentRatio = Math.ceil(ratio);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果是窗口缩放场景, DPR 可能是 1.2 , 也可能是 1.2123123 这种, 没啥意义, 统一取整

const lastRatio = container.getConfig().devicePixelRatio ?? 1;

if (lastRatio === ratio || !canvas) {
if (lastRatio === currentRatio || !canvas) {
return;
}

// https://github.com/antvis/G/issues/1143
container.getConfig().devicePixelRatio = ratio;
container.getConfig().devicePixelRatio = currentRatio;
container.resize(width!, height!);

await this.spreadsheet.render(false);
};

private renderByZoomScale = debounce(async (event: Event) => {
const ratio = Math.ceil((event.target as VisualViewport)?.scale);
const target = event.target as VisualViewport;
const ratio = Math.ceil(target?.scale);

/**
* github.com/antvis/S2/issues/2884
* 如果是触控板双指缩放触发的 resize 事件, offsetLeft 可以获取到值
* 如果是浏览器窗口的放大缩小 (command +/-), offsetLeft 始终是 0
*/
const isTouchPadZoom = this.zoomOffsetLeft !== target.offsetLeft;

if (ratio >= 1 && !this.isDevicePixelRatioChange) {
if (ratio >= 1 && isTouchPadZoom && !this.isDevicePixelRatioChange) {
await this.renderByDevicePixelRatio(ratio);
this.zoomOffsetLeft = target.offsetLeft;
}
}, 350);
}
Loading