diff --git a/src/appState.ts b/src/appState.ts index be3a8760..fb9dac66 100644 --- a/src/appState.ts +++ b/src/appState.ts @@ -5,7 +5,7 @@ import { DEFAULT_TEXT_ALIGN, } from "./constants"; import { t } from "./i18n"; -import { AppState, FlooredNumber, NormalizedZoomValue } from "./types"; +import { AppState, NormalizedZoomValue } from "./types"; import { getDateTime } from "./utils"; export const getDefaultAppState = (): Omit< @@ -56,8 +56,8 @@ export const getDefaultAppState = (): Omit< previousSelectedElementIds: {}, resizingElement: null, scrolledOutside: false, - scrollX: 0 as FlooredNumber, - scrollY: 0 as FlooredNumber, + scrollX: 0, + scrollY: 0, selectedElementIds: {}, selectedGroupIds: {}, selectionElement: null, diff --git a/src/components/App.tsx b/src/components/App.tsx index 338c09e4..74484b7f 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -147,7 +147,6 @@ import { getSelectedElements, isOverScrollBars, isSomeElementSelected, - normalizeScroll, } from "../scene"; import Scene from "../scene/Scene"; import { SceneState, ScrollBars } from "../scene/types"; @@ -1745,8 +1744,8 @@ class App extends React.Component { const scaleFactor = distance / gesture.initialDistance; this.setState(({ zoom, scrollX, scrollY, offsetLeft, offsetTop }) => ({ - scrollX: normalizeScroll(scrollX + deltaX / zoom.value), - scrollY: normalizeScroll(scrollY + deltaY / zoom.value), + scrollX: scrollX + deltaX / zoom.value, + scrollY: scrollY + deltaY / zoom.value, zoom: getNewZoom( getNormalizedZoom(initialScale * scaleFactor), zoom, @@ -2157,12 +2156,8 @@ class App extends React.Component { } this.setState({ - scrollX: normalizeScroll( - this.state.scrollX - deltaX / this.state.zoom.value, - ), - scrollY: normalizeScroll( - this.state.scrollY - deltaY / this.state.zoom.value, - ), + scrollX: this.state.scrollX - deltaX / this.state.zoom.value, + scrollY: this.state.scrollY - deltaY / this.state.zoom.value, }); }); const teardown = withBatchedUpdates( @@ -2976,9 +2971,7 @@ class App extends React.Component { const x = event.clientX; const dx = x - pointerDownState.lastCoords.x; this.setState({ - scrollX: normalizeScroll( - this.state.scrollX - dx / this.state.zoom.value, - ), + scrollX: this.state.scrollX - dx / this.state.zoom.value, }); pointerDownState.lastCoords.x = x; return true; @@ -2988,9 +2981,7 @@ class App extends React.Component { const y = event.clientY; const dy = y - pointerDownState.lastCoords.y; this.setState({ - scrollY: normalizeScroll( - this.state.scrollY - dy / this.state.zoom.value, - ), + scrollY: this.state.scrollY - dy / this.state.zoom.value, }); pointerDownState.lastCoords.y = y; return true; @@ -3741,14 +3732,14 @@ class App extends React.Component { if (event.shiftKey) { this.setState(({ zoom, scrollX }) => ({ // on Mac, shift+wheel tends to result in deltaX - scrollX: normalizeScroll(scrollX - (deltaY || deltaX) / zoom.value), + scrollX: scrollX - (deltaY || deltaX) / zoom.value, })); return; } this.setState(({ zoom, scrollX, scrollY }) => ({ - scrollX: normalizeScroll(scrollX - deltaX / zoom.value), - scrollY: normalizeScroll(scrollY - deltaY / zoom.value), + scrollX: scrollX - deltaX / zoom.value, + scrollY: scrollY - deltaY / zoom.value, })); }); diff --git a/src/gesture.ts b/src/gesture.ts index 66b7ef48..4592338b 100644 --- a/src/gesture.ts +++ b/src/gesture.ts @@ -1,11 +1,10 @@ import { PointerCoords } from "./types"; -import { normalizeScroll } from "./scene"; export const getCenter = (pointers: Map) => { const allCoords = Array.from(pointers.values()); return { - x: normalizeScroll(sum(allCoords, (coords) => coords.x) / allCoords.length), - y: normalizeScroll(sum(allCoords, (coords) => coords.y) / allCoords.length), + x: sum(allCoords, (coords) => coords.x) / allCoords.length, + y: sum(allCoords, (coords) => coords.y) / allCoords.length, }; }; diff --git a/src/scene/export.ts b/src/scene/export.ts index 57d3c18f..bf58713a 100644 --- a/src/scene/export.ts +++ b/src/scene/export.ts @@ -5,7 +5,6 @@ import { NonDeletedExcalidrawElement } from "../element/types"; import { getCommonBounds } from "../element/bounds"; import { renderScene, renderSceneToSvg } from "../renderer/renderScene"; import { distance, SVG_NS } from "../utils"; -import { normalizeScroll } from "./scroll"; import { AppState } from "../types"; import { t } from "../i18n"; import { DEFAULT_FONT_FAMILY, DEFAULT_VERTICAL_ALIGN } from "../constants"; @@ -59,8 +58,8 @@ export const exportToCanvas = ( tempCanvas, { viewBackgroundColor: exportBackground ? viewBackgroundColor : null, - scrollX: normalizeScroll(-minX + exportPadding), - scrollY: normalizeScroll(-minY + exportPadding), + scrollX: -minX + exportPadding, + scrollY: -minY + exportPadding, zoom: getDefaultAppState().zoom, remotePointerViewportCoords: {}, remoteSelectedElementIds: {}, diff --git a/src/scene/index.ts b/src/scene/index.ts index 0b98f6f2..36cc4161 100644 --- a/src/scene/index.ts +++ b/src/scene/index.ts @@ -6,7 +6,7 @@ export { getSelectedElements, getTargetElements, } from "./selection"; -export { normalizeScroll, calculateScrollCenter } from "./scroll"; +export { calculateScrollCenter } from "./scroll"; export { hasBackground, hasStroke, diff --git a/src/scene/scroll.ts b/src/scene/scroll.ts index 51cc7da4..c42341fc 100644 --- a/src/scene/scroll.ts +++ b/src/scene/scroll.ts @@ -1,4 +1,4 @@ -import { AppState, FlooredNumber, PointerCoords, Zoom } from "../types"; +import { AppState, PointerCoords, Zoom } from "../types"; import { ExcalidrawElement } from "../element/types"; import { getCommonBounds, getClosestElementBounds } from "../element"; @@ -7,9 +7,6 @@ import { viewportCoordsToSceneCoords, } from "../utils"; -export const normalizeScroll = (pos: number) => - Math.floor(pos) as FlooredNumber; - const isOutsideViewPort = ( appState: AppState, canvas: HTMLCanvasElement | null, @@ -40,16 +37,14 @@ export const centerScrollOn = ({ zoom: Zoom; }) => { return { - scrollX: normalizeScroll( + scrollX: (viewportDimensions.width / 2) * (1 / zoom.value) - - scenePoint.x - - zoom.translation.x * (1 / zoom.value), - ), - scrollY: normalizeScroll( + scenePoint.x - + zoom.translation.x * (1 / zoom.value), + scrollY: (viewportDimensions.height / 2) * (1 / zoom.value) - - scenePoint.y - - zoom.translation.y * (1 / zoom.value), - ), + scenePoint.y - + zoom.translation.y * (1 / zoom.value), }; }; @@ -57,11 +52,11 @@ export const calculateScrollCenter = ( elements: readonly ExcalidrawElement[], appState: AppState, canvas: HTMLCanvasElement | null, -): { scrollX: FlooredNumber; scrollY: FlooredNumber } => { +): { scrollX: number; scrollY: number } => { if (!elements.length) { return { - scrollX: normalizeScroll(0), - scrollY: normalizeScroll(0), + scrollX: 0, + scrollY: 0, }; } let [x1, y1, x2, y2] = getCommonBounds(elements); diff --git a/src/scene/scrollbars.ts b/src/scene/scrollbars.ts index 24f10e7d..19f32759 100644 --- a/src/scene/scrollbars.ts +++ b/src/scene/scrollbars.ts @@ -1,6 +1,6 @@ import { ExcalidrawElement } from "../element/types"; import { getCommonBounds } from "../element"; -import { FlooredNumber, Zoom } from "../types"; +import { Zoom } from "../types"; import { ScrollBars } from "./types"; import { getGlobalCSSVariable } from "../utils"; import { getLanguage } from "../i18n"; @@ -18,8 +18,8 @@ export const getScrollBars = ( scrollY, zoom, }: { - scrollX: FlooredNumber; - scrollY: FlooredNumber; + scrollX: number; + scrollY: number; zoom: Zoom; }, ): ScrollBars => { diff --git a/src/scene/types.ts b/src/scene/types.ts index 5bb3f701..907acf23 100644 --- a/src/scene/types.ts +++ b/src/scene/types.ts @@ -1,9 +1,9 @@ import { ExcalidrawTextElement } from "../element/types"; -import { FlooredNumber, Zoom } from "../types"; +import { Zoom } from "../types"; export type SceneState = { - scrollX: FlooredNumber; - scrollY: FlooredNumber; + scrollX: number; + scrollY: number; // null indicates transparent bg viewBackgroundColor: string | null; zoom: Zoom; @@ -15,8 +15,8 @@ export type SceneState = { }; export type SceneScroll = { - scrollX: FlooredNumber; - scrollY: FlooredNumber; + scrollX: number; + scrollY: number; }; export interface Scene { diff --git a/src/tests/__snapshots__/regressionTests.test.tsx.snap b/src/tests/__snapshots__/regressionTests.test.tsx.snap index 8c8bf78a..83b6ad55 100644 --- a/src/tests/__snapshots__/regressionTests.test.tsx.snap +++ b/src/tests/__snapshots__/regressionTests.test.tsx.snap @@ -12705,7 +12705,7 @@ Object { }, "previousSelectedElementIds": Object {}, "resizingElement": null, - "scrollX": -6, + "scrollX": -5.416666666666667, "scrollY": 0, "scrolledOutside": false, "selectedElementIds": Object { @@ -12725,7 +12725,7 @@ Object { "zenModeEnabled": false, "zoom": Object { "translation": Object { - "x": 0.3333333333333357, + "x": 0.4166666666666714, "y": 0, }, "value": 1, @@ -20330,7 +20330,7 @@ Object { }, "previousSelectedElementIds": Object {}, "resizingElement": null, - "scrollX": 11, + "scrollX": 11.046099290780141, "scrollY": -5, "scrolledOutside": false, "selectedElementIds": Object { @@ -20350,7 +20350,7 @@ Object { "zenModeEnabled": false, "zoom": Object { "translation": Object { - "x": -60.420000000000016, + "x": -59.425, "y": -48.66347517730496, }, "value": 1.99, diff --git a/src/types.ts b/src/types.ts index 6b3b2044..503e8172 100644 --- a/src/types.ts +++ b/src/types.ts @@ -21,7 +21,6 @@ import type { ResolvablePromise } from "./utils"; import { Spreadsheet } from "./charts"; import { Language } from "./i18n"; -export type FlooredNumber = number & { _brand: "FlooredNumber" }; export type Point = Readonly; export type Collaborator = { @@ -68,8 +67,8 @@ export type AppState = { currentItemEndArrowhead: Arrowhead | null; currentItemLinearStrokeSharpness: ExcalidrawElement["strokeSharpness"]; viewBackgroundColor: string; - scrollX: FlooredNumber; - scrollY: FlooredNumber; + scrollX: number; + scrollY: number; cursorButton: "up" | "down"; scrolledOutside: boolean; name: string;