Drop edge scrolling adjustment for mobile (#2346)
This PR makes all edge scrolling distances 32px. ### Change Type - [x] `patch` — Bug fix
This commit is contained in:
parent
5f9ab64838
commit
b58274ced2
4 changed files with 35 additions and 33 deletions
|
@ -95,3 +95,6 @@ export const HIT_TEST_MARGIN = 8
|
||||||
|
|
||||||
/** @internal */
|
/** @internal */
|
||||||
export const EDGE_SCROLL_SPEED = 20
|
export const EDGE_SCROLL_SPEED = 20
|
||||||
|
|
||||||
|
/** @internal */
|
||||||
|
export const EDGE_SCROLL_DISTANCE = 32
|
||||||
|
|
|
@ -1,24 +1,21 @@
|
||||||
import { EDGE_SCROLL_SPEED } from '../constants'
|
import { EDGE_SCROLL_DISTANCE, EDGE_SCROLL_SPEED } from '../constants'
|
||||||
import { Editor } from '../editor/Editor'
|
import { Editor } from '../editor/Editor'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper function to get the scroll offset for a given position.
|
* Helper function to get the scroll proximity factor for a given position.
|
||||||
* The closer the mouse is to the edge of the screen the faster we scroll.
|
* @param position - The mouse position on the axis.
|
||||||
* We also adjust the speed and the start offset based on the screen size and zoom level.
|
* @param dimension - The component dimension on the axis.
|
||||||
*
|
|
||||||
* @param editor - The mouse position on the screen in pixels
|
|
||||||
* @returns How much we should scroll in pixels
|
|
||||||
* @internal
|
* @internal
|
||||||
*/
|
*/
|
||||||
export function getEdgeProximityFactor(position: number, scrollOffset: number, extreme: number) {
|
export function getEdgeProximityFactor(position: number, dimension: number) {
|
||||||
if (position < 0) {
|
if (position < 0) {
|
||||||
return 1
|
return 1
|
||||||
} else if (position > extreme) {
|
} else if (position > dimension) {
|
||||||
return -1
|
return -1
|
||||||
} else if (position < scrollOffset) {
|
} else if (position < EDGE_SCROLL_DISTANCE) {
|
||||||
return (scrollOffset - position) / scrollOffset
|
return (EDGE_SCROLL_DISTANCE - position) / EDGE_SCROLL_DISTANCE
|
||||||
} else if (position > extreme - scrollOffset) {
|
} else if (position > dimension - EDGE_SCROLL_DISTANCE) {
|
||||||
return -(scrollOffset - extreme + position) / scrollOffset
|
return -(EDGE_SCROLL_DISTANCE - dimension + position) / EDGE_SCROLL_DISTANCE
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
@ -38,22 +35,17 @@ export function moveCameraWhenCloseToEdge(editor: Editor) {
|
||||||
const zoomLevel = editor.getZoomLevel()
|
const zoomLevel = editor.getZoomLevel()
|
||||||
const screenBounds = editor.getViewportScreenBounds()
|
const screenBounds = editor.getViewportScreenBounds()
|
||||||
|
|
||||||
// Determines how far from the edges we start the scroll behaviour
|
|
||||||
const insetX = screenBounds.w < 1000 ? 40 : 32
|
|
||||||
const insetY = screenBounds.h < 1000 ? 40 : 32
|
|
||||||
|
|
||||||
// Determines how much the speed is affected by the screen size
|
// Determines how much the speed is affected by the screen size
|
||||||
const screenSizeFactorX = screenBounds.w < 1000 ? 0.612 : 1
|
const screenSizeFactorX = screenBounds.w < 1000 ? 0.612 : 1
|
||||||
const screenSizeFactorY = screenBounds.h < 1000 ? 0.612 : 1
|
const screenSizeFactorY = screenBounds.h < 1000 ? 0.612 : 1
|
||||||
|
|
||||||
// Determines the base speed of the scroll
|
const proximityFactorX = getEdgeProximityFactor(x, screenBounds.w)
|
||||||
const pxSpeed = editor.user.getEdgeScrollSpeed() * EDGE_SCROLL_SPEED
|
const proximityFactorY = getEdgeProximityFactor(y, screenBounds.h)
|
||||||
|
|
||||||
const proximityFactorX = getEdgeProximityFactor(x, insetX, screenBounds.w)
|
|
||||||
const proximityFactorY = getEdgeProximityFactor(y, insetY, screenBounds.h)
|
|
||||||
|
|
||||||
if (proximityFactorX === 0 && proximityFactorY === 0) return
|
if (proximityFactorX === 0 && proximityFactorY === 0) return
|
||||||
|
|
||||||
|
// Determines the base speed of the scroll
|
||||||
|
const pxSpeed = editor.user.getEdgeScrollSpeed() * EDGE_SCROLL_SPEED
|
||||||
const scrollDeltaX = (pxSpeed * proximityFactorX * screenSizeFactorX) / zoomLevel
|
const scrollDeltaX = (pxSpeed * proximityFactorX * screenSizeFactorX) / zoomLevel
|
||||||
const scrollDeltaY = (pxSpeed * proximityFactorY * screenSizeFactorY) / zoomLevel
|
const scrollDeltaY = (pxSpeed * proximityFactorY * screenSizeFactorY) / zoomLevel
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import {
|
||||||
PI2,
|
PI2,
|
||||||
PointsSnapLine,
|
PointsSnapLine,
|
||||||
RotateCorner,
|
RotateCorner,
|
||||||
|
TLGeoShape,
|
||||||
TLSelectionHandle,
|
TLSelectionHandle,
|
||||||
TLShapeId,
|
TLShapeId,
|
||||||
TLShapePartial,
|
TLShapePartial,
|
||||||
|
@ -3903,6 +3904,7 @@ describe('Resizing text from the right edge', () => {
|
||||||
describe('When resizing near the edges of the screen', () => {
|
describe('When resizing near the edges of the screen', () => {
|
||||||
it('resizes past the edge of the screen', () => {
|
it('resizes past the edge of the screen', () => {
|
||||||
editor.user.updateUserPreferences({ edgeScrollSpeed: 1 })
|
editor.user.updateUserPreferences({ edgeScrollSpeed: 1 })
|
||||||
|
const before = editor.getShape<TLGeoShape>(ids.boxA)!
|
||||||
editor
|
editor
|
||||||
.select(ids.boxA)
|
.select(ids.boxA)
|
||||||
.pointerDown(10, 10, {
|
.pointerDown(10, 10, {
|
||||||
|
@ -3910,14 +3912,12 @@ describe('When resizing near the edges of the screen', () => {
|
||||||
target: 'selection',
|
target: 'selection',
|
||||||
handle: 'top_left',
|
handle: 'top_left',
|
||||||
})
|
})
|
||||||
.expectShapeToMatch({ id: ids.boxA, x: 10, y: 10, props: { w: 100, h: 100 } })
|
|
||||||
.pointerMove(10, 25)
|
.pointerMove(10, 25)
|
||||||
jest.advanceTimersByTime(1000)
|
jest.advanceTimersByTime(1000)
|
||||||
editor.expectShapeToMatch({
|
const after = editor.getShape<TLGeoShape>(ids.boxA)!
|
||||||
id: ids.boxA,
|
expect(after.x).toBeLessThan(before.x)
|
||||||
x: -842.5,
|
expect(after.y).toBeLessThan(before.y)
|
||||||
y: -259.58,
|
expect(after.props.w).toBeGreaterThan(before.props.w)
|
||||||
props: { w: 952.5, h: 369.58 },
|
expect(after.props.h).toBeGreaterThan(before.props.h)
|
||||||
})
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,6 +3,7 @@ import {
|
||||||
PointsSnapLine,
|
PointsSnapLine,
|
||||||
SnapLine,
|
SnapLine,
|
||||||
TLArrowShape,
|
TLArrowShape,
|
||||||
|
TLGeoShape,
|
||||||
TLShapeId,
|
TLShapeId,
|
||||||
TLShapePartial,
|
TLShapePartial,
|
||||||
Vec2d,
|
Vec2d,
|
||||||
|
@ -131,6 +132,8 @@ describe('When translating...', () => {
|
||||||
editor.user.updateUserPreferences({ edgeScrollSpeed: 1 })
|
editor.user.updateUserPreferences({ edgeScrollSpeed: 1 })
|
||||||
editor.pointerDown(50, 50, ids.box1).pointerMove(0, 50) // [-50, 0]
|
editor.pointerDown(50, 50, ids.box1).pointerMove(0, 50) // [-50, 0]
|
||||||
|
|
||||||
|
const before = editor.getShape<TLGeoShape>(ids.box1)!
|
||||||
|
|
||||||
jest.advanceTimersByTime(100)
|
jest.advanceTimersByTime(100)
|
||||||
editor
|
editor
|
||||||
// The change is bigger than expected because the camera moves
|
// The change is bigger than expected because the camera moves
|
||||||
|
@ -139,10 +142,14 @@ describe('When translating...', () => {
|
||||||
// The speed in the y position is smaller since we are further away from the edge.
|
// The speed in the y position is smaller since we are further away from the edge.
|
||||||
.pointerMove(0, 25)
|
.pointerMove(0, 25)
|
||||||
jest.advanceTimersByTime(100)
|
jest.advanceTimersByTime(100)
|
||||||
editor
|
editor.pointerUp()
|
||||||
.expectShapeToMatch({ id: ids.box1, x: -280, y: -42.54 })
|
|
||||||
.pointerUp()
|
const after = editor.getShape<TLGeoShape>(ids.box1)!
|
||||||
.expectShapeToMatch({ id: ids.box1, x: -280, y: -42.54 })
|
|
||||||
|
expect(after.x).toBeLessThan(before.x)
|
||||||
|
expect(after.y).toBeLessThan(before.y)
|
||||||
|
expect(after.props.w).toEqual(before.props.w)
|
||||||
|
expect(after.props.h).toEqual(before.props.h)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('translates a single shape near the bottom right edge', () => {
|
it('translates a single shape near the bottom right edge', () => {
|
||||||
|
|
Loading…
Reference in a new issue