@tldraw/editor
Version:
tldraw infinite canvas SDK (editor).
8 lines (7 loc) • 6.86 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../../../../src/lib/editor/managers/EdgeScrollManager/EdgeScrollManager.ts"],
"sourcesContent": ["import { Vec } from '../../../primitives/Vec'\nimport { EASINGS } from '../../../primitives/easings'\nimport { Editor } from '../../Editor'\n\n/** @public */\nexport class EdgeScrollManager {\n\tconstructor(public editor: Editor) {}\n\n\tprivate _isEdgeScrolling = false\n\tprivate _edgeScrollDuration = -1\n\n\t/**\n\t * Update the camera position when the mouse is close to the edge of the screen.\n\t * Run this on every tick when in a state where edge scrolling is enabled.\n\t *\n\t * @public\n\t */\n\tupdateEdgeScrolling(elapsed: number) {\n\t\tconst { editor } = this\n\t\tconst edgeScrollProximityFactor = this.getEdgeScroll()\n\t\tif (edgeScrollProximityFactor.x === 0 && edgeScrollProximityFactor.y === 0) {\n\t\t\tif (this._isEdgeScrolling) {\n\t\t\t\tthis._isEdgeScrolling = false\n\t\t\t\tthis._edgeScrollDuration = 0\n\t\t\t}\n\t\t} else {\n\t\t\tif (!this._isEdgeScrolling) {\n\t\t\t\tthis._isEdgeScrolling = true\n\t\t\t\tthis._edgeScrollDuration = 0\n\t\t\t}\n\t\t\tthis._edgeScrollDuration += elapsed\n\t\t\tif (this._edgeScrollDuration > editor.options.edgeScrollDelay) {\n\t\t\t\tconst eased =\n\t\t\t\t\teditor.options.edgeScrollEaseDuration > 0\n\t\t\t\t\t\t? EASINGS.easeInCubic(\n\t\t\t\t\t\t\t\tMath.min(\n\t\t\t\t\t\t\t\t\t1,\n\t\t\t\t\t\t\t\t\tthis._edgeScrollDuration /\n\t\t\t\t\t\t\t\t\t\t(editor.options.edgeScrollDelay + editor.options.edgeScrollEaseDuration)\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: 1\n\t\t\t\tthis.moveCameraWhenCloseToEdge({\n\t\t\t\t\tx: edgeScrollProximityFactor.x * eased,\n\t\t\t\t\ty: edgeScrollProximityFactor.y * eased,\n\t\t\t\t})\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Helper function to get the scroll proximity factor for a given position.\n\t * @param position - The mouse position on the axis.\n\t * @param dimension - The component dimension on the axis.\n\t * @param isCoarse - Whether the pointer is coarse.\n\t * @param insetStart - Whether the pointer is inset at the start of the axis.\n\t * @param insetEnd - Whether the pointer is inset at the end of the axis.\n\t * @internal\n\t */\n\tprivate getEdgeProximityFactors(\n\t\tposition: number,\n\t\tdimension: number,\n\t\tisCoarse: boolean,\n\t\tinsetStart: boolean,\n\t\tinsetEnd: boolean\n\t) {\n\t\tconst { editor } = this\n\t\tconst dist = editor.options.edgeScrollDistance\n\t\tconst pw = isCoarse ? editor.options.coarsePointerWidth : 0 // pointer width\n\t\tconst pMin = position - pw\n\t\tconst pMax = position + pw\n\t\tconst min = insetStart ? 0 : dist\n\t\tconst max = insetEnd ? dimension : dimension - dist\n\t\tif (pMin < min) {\n\t\t\treturn Math.min(1, (min - pMin) / dist)\n\t\t} else if (pMax > max) {\n\t\t\treturn -Math.min(1, (pMax - max) / dist)\n\t\t}\n\t\treturn 0\n\t}\n\n\tprivate getEdgeScroll() {\n\t\tconst { editor } = this\n\t\tconst {\n\t\t\tinputs: {\n\t\t\t\tcurrentScreenPoint: { x, y },\n\t\t\t},\n\t\t} = editor\n\t\tconst screenBounds = editor.getViewportScreenBounds()\n\n\t\tconst {\n\t\t\tisCoarsePointer,\n\t\t\tinsets: [t, r, b, l],\n\t\t} = editor.getInstanceState()\n\t\tconst proximityFactorX = this.getEdgeProximityFactors(x, screenBounds.w, isCoarsePointer, l, r)\n\t\tconst proximityFactorY = this.getEdgeProximityFactors(y, screenBounds.h, isCoarsePointer, t, b)\n\n\t\treturn {\n\t\t\tx: proximityFactorX,\n\t\t\ty: proximityFactorY,\n\t\t}\n\t}\n\n\t/**\n\t * Moves the camera when the mouse is close to the edge of the screen.\n\t * @public\n\t */\n\tprivate moveCameraWhenCloseToEdge(proximityFactor: { x: number; y: number }) {\n\t\tconst { editor } = this\n\t\tif (!editor.inputs.isDragging || editor.inputs.isPanning || editor.getCameraOptions().isLocked)\n\t\t\treturn\n\n\t\tif (proximityFactor.x === 0 && proximityFactor.y === 0) return\n\n\t\tconst screenBounds = editor.getViewportScreenBounds()\n\n\t\t// Determines how much the speed is affected by the screen size\n\t\tconst screenSizeFactorX = screenBounds.w < 1000 ? 0.612 : 1\n\t\tconst screenSizeFactorY = screenBounds.h < 1000 ? 0.612 : 1\n\n\t\t// Determines the base speed of the scroll\n\t\tconst zoomLevel = editor.getZoomLevel()\n\t\tconst pxSpeed = editor.user.getEdgeScrollSpeed() * editor.options.edgeScrollSpeed\n\t\tconst scrollDeltaX = (pxSpeed * proximityFactor.x * screenSizeFactorX) / zoomLevel\n\t\tconst scrollDeltaY = (pxSpeed * proximityFactor.y * screenSizeFactorY) / zoomLevel\n\n\t\t// update the camera\n\t\tconst { x, y, z } = editor.getCamera()\n\t\teditor.setCamera(new Vec(x + scrollDeltaX, y + scrollDeltaY, z))\n\t}\n}\n"],
"mappings": "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",
"names": []
}