diff --git a/packages/core/src/canvas/index.ts b/packages/core/src/canvas/index.ts index 4e1c98f70..88940b85b 100644 --- a/packages/core/src/canvas/index.ts +++ b/packages/core/src/canvas/index.ts @@ -40,7 +40,7 @@ import Canvas from './model/Canvas'; import CanvasSpot, { CanvasSpotBuiltInTypes, CanvasSpotProps } from './model/CanvasSpot'; import CanvasSpots from './model/CanvasSpots'; import Frame from './model/Frame'; -import { CanvasEvents, CanvasRefreshOptions, ToWorldOption } from './types'; +import { CanvasEvents, CanvasRefreshOptions, SetZoomOptions, ToWorldOption } from './types'; import CanvasView, { FitViewportOptions } from './view/CanvasView'; import FrameView from './view/FrameView'; import { DragSource } from '../utils/sorter/types'; @@ -639,8 +639,8 @@ export default class CanvasModule extends Module { * @example * canvas.setZoom(50); // set zoom to 50% */ - setZoom(value: number | string) { - this.canvas.set('zoom', typeof value === 'string' ? parseFloat(value) : value); + setZoom(value: number | string, opts: SetZoomOptions = {}) { + this.canvas.set('zoom', typeof value === 'string' ? parseFloat(value) : value, opts); return this; } diff --git a/packages/core/src/canvas/model/Canvas.ts b/packages/core/src/canvas/model/Canvas.ts index 7c539f6de..a6f50f0f6 100644 --- a/packages/core/src/canvas/model/Canvas.ts +++ b/packages/core/src/canvas/model/Canvas.ts @@ -1,6 +1,6 @@ import CanvasModule from '..'; import { ModuleModel } from '../../abstract'; -import { Coordinates, CoordinatesTypes, DEFAULT_COORDS } from '../../common'; +import { Coordinates, CoordinatesTypes, DEFAULT_COORDS, ObjectAny } from '../../common'; import { evUpdate as evDeviceUpdate } from '../../device_manager'; import Page from '../../pages/model/Page'; import PagesEvents from '../../pages/types'; @@ -68,11 +68,11 @@ export default class Canvas extends ModuleModel { } } - onZoomChange() { + onZoomChange(m: any, v: any, options: ObjectAny) { const { em, module } = this; const zoom = this.get('zoom'); zoom < 1 && this.set('zoom', 1); - em.trigger(module.events.zoom); + em.trigger(module.events.zoom, { options }); } onCoordsChange() { diff --git a/packages/core/src/canvas/types.ts b/packages/core/src/canvas/types.ts index 4169b76d0..c64e33d95 100644 --- a/packages/core/src/canvas/types.ts +++ b/packages/core/src/canvas/types.ts @@ -1,3 +1,5 @@ +import { SetOptions } from '../common'; + export interface ToScreenOption { toScreen?: boolean; } @@ -18,6 +20,10 @@ export interface CanvasRefreshOptions { all?: boolean; } +export interface SetZoomOptions extends SetOptions { + from?: string; +} + /**{START_EVENTS}*/ export enum CanvasEvents { /** diff --git a/packages/core/src/canvas/view/CanvasView.ts b/packages/core/src/canvas/view/CanvasView.ts index 57490fe52..d22895e5e 100644 --- a/packages/core/src/canvas/view/CanvasView.ts +++ b/packages/core/src/canvas/view/CanvasView.ts @@ -1,4 +1,4 @@ -import { bindAll, isNumber } from 'underscore'; +import { bindAll, isFunction, isNumber } from 'underscore'; import { ModuleView } from '../../abstract'; import { BoxRect, Coordinates, CoordinatesTypes, ElementRect } from '../../common'; import Component from '../../dom_components/model/Component'; @@ -47,7 +47,7 @@ export interface FitViewportOptions { gap?: number | { x: number; y: number }; ignoreHeight?: boolean; el?: HTMLElement; - zoom?: number; + zoom?: number | ((zoom: number) => number); } export default class CanvasView extends ModuleView { @@ -306,15 +306,17 @@ export default class CanvasView extends ModuleView { const zoomRatio = noHeight ? widthRatio : Math.min(widthRatio, heightRatio); const zoom = zoomRatio * 100; - module.setZoom(opts.zoom ?? zoom); + const newZoom = (isFunction(opts.zoom) ? opts.zoom(zoom) : opts.zoom) ?? zoom; + module.setZoom(newZoom, { from: 'fitViewport' }); - // check for the frame witdh is necessary as we're centering the frame via CSS + // check for the frame width is necessary as we're centering the frame via CSS const coordX = -boxRect.x + (frame.width >= canvasWidth ? canvasWidth / 2 - boxWidth / 2 : -gapX); const coordY = -boxRect.y + canvasHeight / 2 - boxHeight / 2; + const zoomDecimal = module.getZoomDecimal(); const coords = { - x: (coordX + gapX) * zoomRatio, - y: (coordY + gapY) * zoomRatio, + x: (coordX + gapX) * zoomDecimal, + y: (coordY + gapY) * zoomDecimal, }; if (noHeight) { @@ -322,7 +324,7 @@ export default class CanvasView extends ModuleView { const canvasWorldHeight = canvasHeight * zoomMltp; const canvasHeightDiff = canvasWorldHeight - canvasHeight; const yDelta = canvasHeightDiff / 2; - coords.y = (-boxRect.y + gapY) * zoomMltp - yDelta / zoomMltp; + coords.y = (-boxRect.y + gapY) * zoomDecimal - yDelta / zoomMltp; } module.setCoords(coords.x, coords.y);