From 8fbbfc1ad5c2d547201514058cff04e146c499aa Mon Sep 17 00:00:00 2001 From: Eric Nguyen Date: Mon, 20 Feb 2023 13:53:07 +0000 Subject: [PATCH] Merged PR 368: Fix toolbar zoom Fix toolbar zoom --- .../SVGReactPanZoom/ui-toolbar/toolbar.tsx | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Components/SVG/SVGReactPanZoom/ui-toolbar/toolbar.tsx b/src/Components/SVG/SVGReactPanZoom/ui-toolbar/toolbar.tsx index 83bb4b0..8d11038 100644 --- a/src/Components/SVG/SVGReactPanZoom/ui-toolbar/toolbar.tsx +++ b/src/Components/SVG/SVGReactPanZoom/ui-toolbar/toolbar.tsx @@ -6,7 +6,7 @@ import { MagnifyingGlassPlusIcon } from '@heroicons/react/24/outline'; import React from 'react'; -import { fromObject, scale, transform, translate } from 'transformation-matrix'; +import { applyToPoint, fromObject, inverse, scale, transform, translate } from 'transformation-matrix'; import { fitToViewer, @@ -51,6 +51,38 @@ function set(value: Value, patch: object, action = null): Value { return Object.freeze(value); } +/** + * Export x,y coords relative to SVG + * @param value + * @param viewerX + * @param viewerY + * @returns {*|{x, y}|{x: number, y: number}} + */ +function getSVGPoint(value: Value, viewerX: number, viewerY: number): PointObjectNotation { + const matrix = fromObject(value); + + const inverseMatrix = inverse(matrix); + return applyToPoint(inverseMatrix, { x: viewerX, y: viewerY }); +} + +export function zoom( + value: Value, + SVGPointX: number, + SVGPointY: number, + scaleFactor: number +): Value { + const matrix = transform( + fromObject(value), + translate(SVGPointX, SVGPointY), + scale(scaleFactor, scaleFactor), + translate(-SVGPointX, -SVGPointY) + ); + + return set(value, { + ...matrix + }); +} + export function Toolbar({ tool, value, @@ -72,16 +104,8 @@ export function Toolbar({ let fittedValue: Value = fitToViewer(value, SVGAlignX, SVGAlignY); if (fittingScale !== undefined) { const { viewerWidth, viewerHeight } = fittedValue; - const matrix = transform( - fromObject(fittedValue), - translate(viewerWidth, viewerHeight), - scale(fittingScale, fittingScale), - translate(-viewerWidth, -viewerHeight) - ); - - fittedValue = set(fittedValue, { - ...matrix - }); + const SVGPoint = getSVGPoint(value, viewerWidth / 2, viewerHeight / 2); + fittedValue = zoom(fittedValue, SVGPoint.x, SVGPoint.y, fittingScale); } onChangeValue(fittedValue);