diff --git a/src/components/App.tsx b/src/components/App.tsx index 71c63c10..1c655eb3 100644 --- a/src/components/App.tsx +++ b/src/components/App.tsx @@ -682,6 +682,7 @@ export class App extends React.Component { { clientX: cursorX, clientY: cursorY }, this.state, this.canvas, + window.devicePixelRatio, ); const element = newTextElement( @@ -808,10 +809,6 @@ export class App extends React.Component { this.canvas.addEventListener("wheel", this.handleWheel, { passive: false, }); - - this.canvas - .getContext("2d") - ?.setTransform(canvasScale, 0, 0, canvasScale, 0, 0); } else { this.canvas?.removeEventListener("wheel", this.handleWheel); } @@ -823,6 +820,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); const element = getElementAtPosition( @@ -923,6 +921,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); const elementAtPosition = getElementAtPosition( @@ -974,6 +973,7 @@ export class App extends React.Component { { sceneX: centerElementX, sceneY: centerElementY }, this.state, this.canvas, + window.devicePixelRatio, ); textX = centerElementXInViewport; @@ -1048,6 +1048,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); this.savePointer(pointerCoords); if (gesture.pointers.has(event.pointerId)) { @@ -1096,6 +1097,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); if (this.state.multiElement) { const { multiElement } = this.state; @@ -1247,6 +1249,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); let lastX = x; let lastY = y; @@ -1657,6 +1660,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); if (distance2d(x, y, originX, originY) < DRAGGING_THRESHOLD) { return; @@ -1675,6 +1679,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); const deltaX = x - lastX; const deltaY = y - lastY; @@ -1891,6 +1896,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); selectedElements.forEach(element => { @@ -1916,6 +1922,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); let width = distance(originX, x); @@ -2019,6 +2026,7 @@ export class App extends React.Component { event, this.state, this.canvas, + window.devicePixelRatio, ); mutateElement(draggingElement, { points: [ @@ -2184,6 +2192,7 @@ export class App extends React.Component { { clientX: cursorX, clientY: cursorY }, this.state, this.canvas, + window.devicePixelRatio, ); const dx = x - elementsCenterX; @@ -2270,6 +2279,7 @@ export class App extends React.Component { }, this.state, this.canvas, + window.devicePixelRatio, ); }); const { atLeastOneVisibleElement, scrollBars } = renderScene( diff --git a/src/renderer/renderElement.ts b/src/renderer/renderElement.ts index 2b771242..2c742a93 100644 --- a/src/renderer/renderElement.ts +++ b/src/renderer/renderElement.ts @@ -64,6 +64,10 @@ function generateElementCanvas( const rc = rough.canvas(canvas); drawElementOnCanvas(element, rc, context); context.translate(-CANVAS_PADDING, -CANVAS_PADDING); + context.scale( + 1 / (window.devicePixelRatio * zoom), + 1 / (window.devicePixelRatio * zoom), + ); return { element, canvas, canvasZoom: zoom, canvasOffsetX, canvasOffsetY }; } diff --git a/src/renderer/renderScene.ts b/src/renderer/renderScene.ts index 19ebe79a..8426edfd 100644 --- a/src/renderer/renderScene.ts +++ b/src/renderer/renderScene.ts @@ -55,6 +55,7 @@ export function renderScene( const elements = allElements.filter(element => !element.isDeleted); const context = canvas.getContext("2d")!; + context.scale(scale, scale); // When doing calculations based on canvas width we should used normalized one const normalizedCanvasWidth = canvas.width / scale; @@ -205,8 +206,9 @@ export function renderScene( } // Paint scrollbars + let scrollBars; if (renderScrollbars) { - const scrollBars = getScrollBars( + scrollBars = getScrollBars( elements, normalizedCanvasWidth, normalizedCanvasHeight, @@ -231,10 +233,11 @@ export function renderScene( }); context.fillStyle = fillStyle; context.strokeStyle = strokeStyle; - return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars }; } - return { atLeastOneVisibleElement: visibleElements.length > 0 }; + context.scale(1 / scale, 1 / scale); + + return { atLeastOneVisibleElement: visibleElements.length > 0, scrollBars }; } function isVisibleElement( diff --git a/src/scene/export.ts b/src/scene/export.ts index 9e03c9b5..bdad08db 100644 --- a/src/scene/export.ts +++ b/src/scene/export.ts @@ -36,7 +36,6 @@ export function exportToCanvas( const height = distance(minY, maxY) + exportPadding * 2; const tempCanvas: any = createCanvas(width, height); - tempCanvas.getContext("2d")?.scale(scale, scale); renderScene( elements, diff --git a/src/scene/zoom.ts b/src/scene/zoom.ts index ed8ebf1a..52aba792 100644 --- a/src/scene/zoom.ts +++ b/src/scene/zoom.ts @@ -1,4 +1,4 @@ -export function getZoomOrigin(canvas: HTMLCanvasElement | null) { +export function getZoomOrigin(canvas: HTMLCanvasElement | null, scale: number) { if (canvas === null) { return { x: 0, y: 0 }; } @@ -7,8 +7,8 @@ export function getZoomOrigin(canvas: HTMLCanvasElement | null) { return { x: 0, y: 0 }; } - const normalizedCanvasWidth = canvas.width / context.getTransform().a; - const normalizedCanvasHeight = canvas.height / context.getTransform().d; + const normalizedCanvasWidth = canvas.width / scale; + const normalizedCanvasHeight = canvas.height / scale; return { x: normalizedCanvasWidth / 2, diff --git a/src/utils.ts b/src/utils.ts index 52701899..7fb16485 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -157,8 +157,9 @@ export function viewportCoordsToSceneCoords( zoom: number; }, canvas: HTMLCanvasElement | null, + scale: number, ) { - const zoomOrigin = getZoomOrigin(canvas); + const zoomOrigin = getZoomOrigin(canvas, scale); const clientXWithZoom = zoomOrigin.x + (clientX - zoomOrigin.x) / zoom; const clientYWithZoom = zoomOrigin.y + (clientY - zoomOrigin.y) / zoom; @@ -180,8 +181,9 @@ export function sceneCoordsToViewportCoords( zoom: number; }, canvas: HTMLCanvasElement | null, + scale: number, ) { - const zoomOrigin = getZoomOrigin(canvas); + const zoomOrigin = getZoomOrigin(canvas, scale); const sceneXWithZoomAndScroll = zoomOrigin.x - (zoomOrigin.x - sceneX - scrollX) * zoom; const sceneYWithZoomAndScroll =