Skip to content

Commit 6e2e3e8

Browse files
authored
fix: refactor size observer for immediate resizing (#543)
Summary: This PR fixes a glitch where the canvas would look stretched for a moment when resizing the viewport. The PixelSizeObserver relied on the animation loop calling getAndResetChanged() for resizing which introduced a one frame delay. I added a callback instead of waiting for the next animation frame to mitigate it.
1 parent 40f3756 commit 6e2e3e8

2 files changed

Lines changed: 13 additions & 23 deletions

File tree

packages/core/src/idetik.ts

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,13 @@ export class Idetik {
112112
sizeDependents.push(viewport.element);
113113
}
114114
}
115-
this.sizeObserver_ = new PixelSizeObserver(sizeDependents);
115+
this.sizeObserver_ = new PixelSizeObserver(sizeDependents, () => {
116+
this.renderer_.updateSize();
117+
for (const viewport of this.viewports_) {
118+
viewport.updateSize();
119+
this.renderer_.render(viewport);
120+
}
121+
});
116122
}
117123

118124
public get renderedObjects() {
@@ -156,11 +162,6 @@ export class Idetik {
156162
private animate(timestamp?: DOMHighResTimeStamp) {
157163
if (this.stats_) this.stats_.begin();
158164

159-
// Must resize before render b/c changing canvas coordinate space clears it.
160-
if (this.sizeObserver_.getAndResetChanged()) {
161-
this.updateSize();
162-
}
163-
164165
for (const viewport of this.viewports_) {
165166
this.renderer_.render(viewport);
166167
}
@@ -190,11 +191,4 @@ export class Idetik {
190191
this.lastAnimationId_ = undefined;
191192
}
192193
}
193-
194-
private updateSize() {
195-
this.renderer_.updateSize();
196-
for (const viewport of this.viewports_) {
197-
viewport.updateSize();
198-
}
199-
}
200194
}

packages/core/src/utilities/pixel_size_observer.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@ export class PixelSizeObserver {
77
private resizeObserver_?: ResizeObserver;
88
private mediaQuery_?: MediaQueryList;
99
private onMediaQueryChange_?: () => void;
10-
private changed_ = false;
10+
private onChange_: () => void;
1111

12-
constructor(elements: ReadonlyArray<HTMLElement> = []) {
12+
constructor(elements: ReadonlyArray<HTMLElement> = [], onChange: () => void) {
1313
this.elements_ = elements;
14+
this.onChange_ = onChange;
1415
}
1516

1617
public connect() {
@@ -21,8 +22,9 @@ export class PixelSizeObserver {
2122
);
2223
return;
2324
}
25+
2426
this.resizeObserver_ = new ResizeObserver(() => {
25-
this.changed_ = true;
27+
this.onChange_();
2628
});
2729

2830
for (const element of this.elements_) {
@@ -32,12 +34,6 @@ export class PixelSizeObserver {
3234
this.startDevicePixelRatioObserver();
3335
}
3436

35-
public getAndResetChanged() {
36-
const wasChanged = this.changed_;
37-
this.changed_ = false;
38-
return wasChanged;
39-
}
40-
4137
private startDevicePixelRatioObserver() {
4238
// this media query needs to be updated after a change is detected, so we use a one-time
4339
// event listener that re-registers itself with the new value
@@ -46,7 +42,7 @@ export class PixelSizeObserver {
4642
`(resolution: ${window.devicePixelRatio}dppx)`
4743
);
4844
this.onMediaQueryChange_ = () => {
49-
this.changed_ = true;
45+
this.onChange_();
5046
this.startDevicePixelRatioObserver();
5147
};
5248
this.mediaQuery_.addEventListener("change", this.onMediaQueryChange_, {

0 commit comments

Comments
 (0)