Fix an issue with the minimap (#3617)

In some cases (when you clicked close to the current viewport area) the
minimap would not change the camera position. This is because the
`clampedPoint` calculation would offset the clicked position slightly
and then the `clampedPoint` would land inside the currently viewport.

With this change we will treat every click outside of the viewport (but
still within allowed bounds) as a change that requires use to change the
camera position.

Before


https://github.com/tldraw/tldraw/assets/2523721/ded202d1-94d7-4b40-ba77-45d283e4fa60

After


https://github.com/tldraw/tldraw/assets/2523721/2ccee77d-ec0e-4997-b51d-c14676657a94


### Change Type

<!--  Please select a 'Scope' label ️ -->

- [ ] `sdk` — Changes the tldraw SDK
- [ ] `dotcom` — Changes the tldraw.com web app
- [ ] `docs` — Changes to the documentation, examples, or templates.
- [ ] `vs code` — Changes to the vscode plugin
- [x] `internal` — Does not affect user-facing stuff

<!--  Please select a 'Type' label ️ -->

- [x] `bugfix` — Bug fix
- [ ] `feature` — New feature
- [ ] `improvement` — Improving existing features
- [ ] `chore` — Updating dependencies, other boring stuff
- [ ] `galaxy brain` — Architectural changes
- [ ] `tests` — Changes to any test code
- [ ] `tools` — Changes to infrastructure, CI, internal scripts,
debugging tools, etc.
- [ ] `dunno` — I don't know


### Test Plan

1. Use minimap in various ways to make sure it still works correctly.
The change targets the `pointerDown` event, but I did also refactor one
method that is also used by double click so it makes sense to test that
as well. Make sure you are not double clicking since we don't use the
same logic there.

- [ ] Unit Tests
- [ ] End to end tests

### Release Notes

- Fixes clicking on the minimap when we clicked just slightly outside of
the current viewport.
pull/3625/head
Mitja Bezenšek 2024-04-26 15:00:43 +02:00 zatwierdzone przez GitHub
rodzic 029116fefd
commit de55259c92
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
2 zmienionych plików z 24 dodań i 31 usunięć

Wyświetl plik

@ -1,5 +1,6 @@
import {
ANIMATION_MEDIUM_MS,
Box,
TLPointerEventInfo,
Vec,
getPointerInfo,
@ -74,26 +75,33 @@ export function DefaultMinimap() {
false
)
const clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(
e.clientX,
e.clientY,
false,
true
const _vpPageBounds = editor.getViewportPageBounds()
const commonBounds = minimapRef.current.getContentPageBounds()
const allowedBounds = new Box(
commonBounds.x - _vpPageBounds.width / 2,
commonBounds.y - _vpPageBounds.height / 2,
commonBounds.width + _vpPageBounds.width,
commonBounds.height + _vpPageBounds.height
)
const _vpPageBounds = editor.getViewportPageBounds()
minimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)
if (minimapRef.current.isInViewport) {
minimapRef.current.originPagePoint.setTo(clampedPoint)
minimapRef.current.originPageCenter.setTo(_vpPageBounds.center)
} else {
// If we clicked inside of the allowed area, but outside of the viewport
if (allowedBounds.containsPoint(point) && !_vpPageBounds.containsPoint(point)) {
minimapRef.current.isInViewport = _vpPageBounds.containsPoint(point)
const delta = Vec.Sub(_vpPageBounds.center, _vpPageBounds.point)
const pagePoint = Vec.Add(point, delta)
minimapRef.current.originPagePoint.setTo(pagePoint)
minimapRef.current.originPageCenter.setTo(point)
editor.centerOnPoint(point, { duration: ANIMATION_MEDIUM_MS })
} else {
const clampedPoint = minimapRef.current.minimapScreenPointToPagePoint(
e.clientX,
e.clientY,
false,
true
)
minimapRef.current.isInViewport = _vpPageBounds.containsPoint(clampedPoint)
minimapRef.current.originPagePoint.setTo(clampedPoint)
minimapRef.current.originPageCenter.setTo(_vpPageBounds.center)
}
function release(e: PointerEvent) {

Wyświetl plik

@ -170,13 +170,12 @@ export class MinimapManager {
clampToBounds = false
) => {
const { editor } = this
const viewportPageBounds = editor.getViewportPageBounds()
const vpPageBounds = editor.getViewportPageBounds()
let { x: px, y: py } = this.getMinimapPagePoint(x, y)
if (clampToBounds) {
const shapesPageBounds = this.editor.getCurrentPageBounds() ?? new Box()
const vpPageBounds = viewportPageBounds
const minX = shapesPageBounds.minX - vpPageBounds.width / 2
const maxX = shapesPageBounds.maxX + vpPageBounds.width / 2
@ -188,22 +187,8 @@ export class MinimapManager {
const ly = Math.max(0, minY + vpPageBounds.height - py)
const ry = Math.max(0, -(maxY - vpPageBounds.height - py))
const ql = Math.max(0, lx - rx)
const qr = Math.max(0, rx - lx)
const qt = Math.max(0, ly - ry)
const qb = Math.max(0, ry - ly)
if (ql && ql > qr) {
px += ql / 2
} else if (qr) {
px -= qr / 2
}
if (qt && qt > qb) {
py += qt / 2
} else if (qb) {
py -= qb / 2
}
px += (lx - rx) / 2
py += (ly - ry) / 2
px = clamp(px, minX, maxX)
py = clamp(py, minY, maxY)