diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/TransformControl.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/TransformControl.tsx index b5089d98ceb0538e8514e2a5aaaba54b208d476a..420b88395d6efa0c862876116bc5c56c848d1bfc 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/TransformControl.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/Control/TransformControl.tsx @@ -27,24 +27,24 @@ export const ZoomControl = () => { const t = useI18n() return <> - - @@ -64,8 +64,8 @@ export const TranslateControl = () => { return } diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx index 59bf2d54a736dda4fdb50906b8956bf00f442245..42a852030da607f2e5cbe00dbed0458caf3580ec 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/ModelStructure/index.tsx @@ -114,18 +114,10 @@ const ModelStructureComp = ({ width, height }: WindowSize) => { const { clientX, clientY, deltaY, ctrlKey, metaKey } = ev if (ctrlKey || metaKey) { - const scaleChange = deltaY > 0 ? -0.04 : 0.02 const offsetX = clientX - translate.x const offsetY = clientY - translate.y - // When zooming, the mouse position is used as transformOrigin, - // so translate needs to be updated. - setTranslate({ - x: translate.x - offsetX * scaleChange, - y: translate.y - offsetY * scaleChange - }) - - deltaY > 0 ? zoomIn() : zoomOut() + deltaY > 0 ? zoomIn({ offsetX, offsetY }) : zoomOut({ offsetX, offsetY }) } else setTranslate({ x: translate.x, diff --git a/plugins/mindstudio-insight-plugins/ModelVis/app/src/stores/graph.ts b/plugins/mindstudio-insight-plugins/ModelVis/app/src/stores/graph.ts index 8957ba3ab966856a67380758a93cdfbf04da44c1..1f1af6fbbdc0e94d79fa0621eeda2fe8c8cd6a4b 100644 --- a/plugins/mindstudio-insight-plugins/ModelVis/app/src/stores/graph.ts +++ b/plugins/mindstudio-insight-plugins/ModelVis/app/src/stores/graph.ts @@ -19,7 +19,7 @@ import { RingCache } from "libs" export const searchResultAtom = atom() export const translateAtom = atom({ x: 0, y: 0 }) -export const translateCacheAtom = atom<{[key:string]:Translate}>({}) +export const translateCacheAtom = atom<{ [key: string]: Translate }>({}) const ScaleInExpo = 0.96 const ScaleUpExpo = 1.02 @@ -28,16 +28,44 @@ const MinZoomRatio = 0.1 export const zoomAtom = atom(1) -export const zoomInAtom = atom(null, (get, set) => { - if (get(zoomAtom) > MinZoomRatio) set(zoomAtom, c => Math.max(c * ScaleInExpo, MinZoomRatio)) +export const zoomInAtom = atom(null, (get, set, param?: { offsetX: number, offsetY: number }) => { + const translate = get(translateAtom); + + if (get(zoomAtom) > MinZoomRatio) { + const scaleChange = -0.04 + const offsetX = param?.offsetX ?? window.innerWidth / 2 - translate.x + const offsetY = param?.offsetY ?? window.innerHeight / 2 - translate.y + + // When zooming, the mouse position is used as transformOrigin, + // so translate needs to be updated. + set(translateAtom, { + x: translate.x - offsetX * scaleChange, + y: translate.y - offsetY * scaleChange + }) + set(zoomAtom, c => Math.max(c * ScaleInExpo, MinZoomRatio)) + } }) export const resetZoomAtom = atom(null, (get, set) => { if (get(zoomAtom) !== 1) set(zoomAtom, _ => 1) }) -export const zoomOutAtom = atom(null, (get, set) => { - if (get(zoomAtom) < MaxZoomRatio) set(zoomAtom, c => Math.min(c * ScaleUpExpo, MaxZoomRatio)) +export const zoomOutAtom = atom(null, (get, set, param?: { offsetX: number, offsetY: number }) => { + const translate = get(translateAtom); + + if (get(zoomAtom) < MaxZoomRatio) { + const scaleChange = 0.02 + const offsetX = param?.offsetX ?? window.innerWidth / 2 - translate.x + const offsetY = param?.offsetY ?? window.innerHeight / 2 - translate.y + + // When zooming, the mouse position is used as transformOrigin, + // so translate needs to be updated. + set(translateAtom, { + x: translate.x - offsetX * scaleChange, + y: translate.y - offsetY * scaleChange + }) + set(zoomAtom, c => Math.min(c * ScaleUpExpo, MaxZoomRatio)) + } }) export const useZoom = () => {