Fix browser zoom issues by not caching devicePixelRatio (#27)

When devicePixelRatio changes, a window resize event will fired, which should fix both #25 and #9.

To test this, I focused the location bar and zoomed into the page.

Before this PR:

![image](https://user-images.githubusercontent.com/150329/38972079-630a0fa8-4353-11e8-8278-3e33fda5ae6e.png)

After this PR:

![image](https://user-images.githubusercontent.com/150329/38972082-6847a2d2-4353-11e8-8d5b-4a5bd1ed9d03.png)


Fixes #25 
Fixes #9
This commit is contained in:
Jamie Wong
2018-04-18 22:18:37 -07:00
committed by GitHub
parent 2bfb2ae1bd
commit 84504f650a
3 changed files with 27 additions and 16 deletions
+12 -8
View File
@@ -9,8 +9,6 @@ import {FontFamily, FontSize, Colors} from './style'
import {CanvasContext} from './canvas-context'
import {TextureCachedRenderer} from './texture-cached-renderer'
const DEVICE_PIXEL_RATIO = window.devicePixelRatio
interface FlamechartMinimapViewProps {
flamechart: Flamechart
configSpaceViewportRect: Rect
@@ -44,7 +42,7 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
}
private minimapOrigin() {
return new Vec2(0, Sizes.FRAME_HEIGHT * DEVICE_PIXEL_RATIO)
return new Vec2(0, Sizes.FRAME_HEIGHT * window.devicePixelRatio)
}
private configSpaceSize() {
@@ -64,7 +62,7 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
}
private logicalToPhysicalViewSpace() {
return AffineTransform.withScale(new Vec2(DEVICE_PIXEL_RATIO, DEVICE_PIXEL_RATIO))
return AffineTransform.withScale(new Vec2(window.devicePixelRatio, window.devicePixelRatio))
}
private windowToLogicalViewSpace() {
@@ -152,8 +150,8 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
).times(this.logicalToPhysicalViewSpace())
const targetInterval = logicalToConfig.transformVector(new Vec2(200, 1)).x
const physicalViewSpaceFrameHeight = Sizes.FRAME_HEIGHT * DEVICE_PIXEL_RATIO
const physicalViewSpaceFontSize = FontSize.LABEL * DEVICE_PIXEL_RATIO
const physicalViewSpaceFrameHeight = Sizes.FRAME_HEIGHT * window.devicePixelRatio
const physicalViewSpaceFontSize = FontSize.LABEL * window.devicePixelRatio
const LABEL_PADDING_PX = (physicalViewSpaceFrameHeight - physicalViewSpaceFontSize) / 2
ctx.font = `${physicalViewSpaceFontSize}px/${physicalViewSpaceFrameHeight}px ${
@@ -187,6 +185,10 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
}
}
onWindowResize = () => {
this.onBeforeFrame()
}
componentWillReceiveProps(nextProps: FlamechartMinimapViewProps) {
if (this.props.flamechart !== nextProps.flamechart) {
if (this.cachedRenderer) {
@@ -199,10 +201,12 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
}
componentDidMount() {
window.addEventListener('resize', this.onWindowResize)
this.props.canvasContext.addBeforeFrameHandler(this.onBeforeFrame)
}
componentWillUnmount() {
window.removeEventListener('resize', this.onWindowResize)
this.props.canvasContext.removeBeforeFrameHandler(this.onBeforeFrame)
}
@@ -222,8 +226,8 @@ export class FlamechartMinimapView extends Component<FlamechartMinimapViewProps,
// Still initializing: don't resize yet
if (width === 0 || height === 0) return
const scaledWidth = width * DEVICE_PIXEL_RATIO
const scaledHeight = height * DEVICE_PIXEL_RATIO
const scaledWidth = width * window.devicePixelRatio
const scaledHeight = height * window.devicePixelRatio
if (scaledWidth === this.overlayCanvas.width && scaledHeight === this.overlayCanvas.height)
return
+8 -8
View File
@@ -59,8 +59,6 @@ function trimTextMid(ctx: CanvasRenderingContext2D, text: string, maxWidth: numb
return buildTrimmedText(text, lo)
}
const DEVICE_PIXEL_RATIO = window.devicePixelRatio
/**
* Component to visualize a Flamechart and interact with it via hovering,
* zooming, and panning.
@@ -143,7 +141,7 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
}
private logicalToPhysicalViewSpace() {
return AffineTransform.withScale(new Vec2(DEVICE_PIXEL_RATIO, DEVICE_PIXEL_RATIO))
return AffineTransform.withScale(new Vec2(window.devicePixelRatio, window.devicePixelRatio))
}
private resizeOverlayCanvasIfNeeded() {
@@ -162,8 +160,8 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
// Still initializing: don't resize yet
if (width === 0 || height === 0) return
const scaledWidth = width * DEVICE_PIXEL_RATIO
const scaledHeight = height * DEVICE_PIXEL_RATIO
const scaledWidth = width * window.devicePixelRatio
const scaledHeight = height * window.devicePixelRatio
if (scaledWidth === this.overlayCanvas.width && scaledHeight === this.overlayCanvas.height)
return
@@ -180,8 +178,9 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
const configToPhysical = this.configSpaceToPhysicalViewSpace()
const physicalViewSpaceFontSize = FontSize.LABEL * DEVICE_PIXEL_RATIO
const physicalViewSpaceFrameHeight = this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT * DEVICE_PIXEL_RATIO
const physicalViewSpaceFontSize = FontSize.LABEL * window.devicePixelRatio
const physicalViewSpaceFrameHeight =
this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT * window.devicePixelRatio
const physicalViewSize = this.physicalViewSize()
@@ -328,7 +327,8 @@ export class FlamechartPanZoomView extends ReloadableComponent<FlamechartPanZoom
const ctx = this.overlayCtx
if (!ctx) return
const physicalViewSpaceFrameHeight = this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT * DEVICE_PIXEL_RATIO
const physicalViewSpaceFrameHeight =
this.LOGICAL_VIEW_SPACE_FRAME_HEIGHT * window.devicePixelRatio
const physicalViewSize = this.physicalViewSize()
const configToPhysical = this.configSpaceToPhysicalViewSpace()
+7
View File
@@ -41,7 +41,14 @@ export function itReduce<T, U>(it: Iterable<T>, f: (a: U, b: T) => U, init: U):
// NOTE: This blindly assumes the same result across contexts.
const measureTextCache = new Map<string, number>()
let lastDevicePixelRatio = -1
export function cachedMeasureTextWidth(ctx: CanvasRenderingContext2D, text: string): number {
if (window.devicePixelRatio !== lastDevicePixelRatio) {
// This cache is no longer valid!
measureTextCache.clear()
lastDevicePixelRatio = window.devicePixelRatio
}
if (!measureTextCache.has(text)) {
measureTextCache.set(text, ctx.measureText(text).width)
}