Prevent overlay content disappearing at some browser zoom levels (#2483)

This essentially reverts the change from #1858 – it seems to be no
longer necessary after we applied the transforms to each overlay item
individually rather than applying a single transform to the outer
container.

This fixes an issue where at certain zoom levels, overlay elements would
disappear when their parent div/svg (that we use for positioning) went
offscreen while their overflowing contents (the stuff you could see) did
not.

todos before merging
- [ ] test on android and ios
- [ ] test on windows


### Change Type

- [x] `patch` — Bug fix

[^1]: publishes a `patch` release, for devDependencies use `internal`
[^2]: will not publish a new version

### Release Notes

- removes the internal `useDprMultiple` hook
This commit is contained in:
David Sheldrick 2024-01-17 10:44:40 +00:00 committed by GitHub
parent eee6c4fe7b
commit 8eba6704df
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 14 additions and 39 deletions

View file

@ -30,8 +30,6 @@
--layer-following-indicator: 1000; --layer-following-indicator: 1000;
/* Misc */ /* Misc */
--tl-zoom: 1; --tl-zoom: 1;
--tl-dpr-multiple: 100;
--tl-dpr-multiple-px: calc(var(--tl-dpr-multiple) * 1px);
/* Cursor SVGs */ /* Cursor SVGs */
--tl-cursor-none: none; --tl-cursor-none: none;
@ -256,8 +254,6 @@ input,
position: absolute; position: absolute;
top: 0px; top: 0px;
left: 0px; left: 0px;
height: var(--tl-dpr-multiple-px);
width: var(--tl-dpr-multiple-px);
overflow: visible; overflow: visible;
pointer-events: none; pointer-events: none;
transform-origin: top left; transform-origin: top left;
@ -267,8 +263,6 @@ input,
position: absolute; position: absolute;
top: 0px; top: 0px;
left: 0px; left: 0px;
height: var(--tl-dpr-multiple-px);
width: var(--tl-dpr-multiple-px);
pointer-events: none; pointer-events: none;
} }

View file

@ -21,7 +21,6 @@ import { Editor } from './editor/Editor'
import { TLStateNodeConstructor } from './editor/tools/StateNode' import { TLStateNodeConstructor } from './editor/tools/StateNode'
import { ContainerProvider, useContainer } from './hooks/useContainer' import { ContainerProvider, useContainer } from './hooks/useContainer'
import { useCursor } from './hooks/useCursor' import { useCursor } from './hooks/useCursor'
import { useDPRMultiple } from './hooks/useDPRMultiple'
import { useDarkMode } from './hooks/useDarkMode' import { useDarkMode } from './hooks/useDarkMode'
import { EditorContext, useEditor } from './hooks/useEditor' import { EditorContext, useEditor } from './hooks/useEditor'
import { import {
@ -356,7 +355,6 @@ function Layout({
useForceUpdate() useForceUpdate()
useFocusEvents(autoFocus) useFocusEvents(autoFocus)
useOnMount(onMount) useOnMount(onMount)
useDPRMultiple()
const editor = useEditor() const editor = useEditor()
editor.updateViewportScreenBounds() editor.updateViewportScreenBounds()

View file

@ -2,11 +2,11 @@ import { track, useQuickReactor, useStateTracking } from '@tldraw/state'
import { TLShape, TLShapeId } from '@tldraw/tlschema' import { TLShape, TLShapeId } from '@tldraw/tlschema'
import * as React from 'react' import * as React from 'react'
import { ShapeUtil } from '../editor/shapes/ShapeUtil' import { ShapeUtil } from '../editor/shapes/ShapeUtil'
import { nearestMultiple } from '../hooks/useDPRMultiple'
import { useEditor } from '../hooks/useEditor' import { useEditor } from '../hooks/useEditor'
import { useEditorComponents } from '../hooks/useEditorComponents' import { useEditorComponents } from '../hooks/useEditorComponents'
import { Mat } from '../primitives/Mat' import { Mat } from '../primitives/Mat'
import { toDomPrecision } from '../primitives/utils' import { toDomPrecision } from '../primitives/utils'
import { nearestMultiple } from '../utils/nearestMultiple'
import { OptionalErrorBoundary } from './ErrorBoundary' import { OptionalErrorBoundary } from './ErrorBoundary'
/* /*

View file

@ -1,30 +0,0 @@
import { react } from '@tldraw/state'
import * as React from 'react'
import { useContainer } from './useContainer'
import { useEditor } from './useEditor'
// Euclidean algorithm to find the GCD
function gcd(a: number, b: number): number {
return b === 0 ? a : gcd(b, a % b)
}
// Returns the lowest value that the given number can be multiplied by to reach an integer
export function nearestMultiple(float: number) {
const decimal = float.toString().split('.')[1]
if (!decimal) return 1
const denominator = Math.pow(10, decimal.length)
const numerator = parseInt(decimal, 10)
return denominator / gcd(numerator, denominator)
}
export function useDPRMultiple() {
const editor = useEditor()
const container = useContainer()
React.useEffect(() => {
return react('useDPRMultiple', () => {
const dpr = editor.getInstanceState().devicePixelRatio
container.style.setProperty('--tl-dpr-multiple', nearestMultiple(dpr).toString())
})
}, [editor, container])
}

View file

@ -0,0 +1,13 @@
// Euclidean algorithm to find the GCD
function gcd(a: number, b: number): number {
return b === 0 ? a : gcd(b, a % b)
}
// Returns the lowest value that the given number can be multiplied by to reach an integer
export function nearestMultiple(float: number) {
const decimal = float.toString().split('.')[1]
if (!decimal) return 1
const denominator = Math.pow(10, decimal.length)
const numerator = parseInt(decimal, 10)
return denominator / gcd(numerator, denominator)
}