diff --git a/src/canvas/view/CanvasView.ts b/src/canvas/view/CanvasView.ts index 24a7a15ed..e34e6d609 100644 --- a/src/canvas/view/CanvasView.ts +++ b/src/canvas/view/CanvasView.ts @@ -19,6 +19,11 @@ export interface MarginPaddingOffsets { paddingLeft?: number; } +export type ElementPosOpts = { + avoidFrameOffset?: boolean; + avoidFrameZoom?: boolean; + noScroll?: boolean; +}; export default class CanvasView extends ModuleView { events() { return { @@ -193,7 +198,7 @@ export default class CanvasView extends ModuleView { * @param {HTMLElement} el * @return { {top: number, left: number, width: number, height: number} } */ - offset(el?: HTMLElement, opts: any = {}) { + offset(el?: HTMLElement, opts: ElementPosOpts = {}) { const rect = getElRect(el); const docBody = el?.ownerDocument.body; const { noScroll } = opts; @@ -243,23 +248,26 @@ export default class CanvasView extends ModuleView { /** * Returns element's rect info * @param {HTMLElement} el + * @param {object} opts * @return { {top: number, left: number, width: number, height: number, zoom: number, rect: any} } * @public */ - getElementPos(el: HTMLElement, opts: any = {}) { + getElementPos(el: HTMLElement, opts: ElementPosOpts = {}) { const zoom = this.getZoom(); - const opt = opts || {}; const frameOffset = this.getFrameOffset(el); const canvasEl = this.el; const canvasOffset = this.getCanvasOffset(); const elRect = this.offset(el, opts); - const frameTop = opt.avoidFrameOffset ? 0 : frameOffset.top; - const frameLeft = opt.avoidFrameOffset ? 0 : frameOffset.left; + const frameTop = opts.avoidFrameOffset ? 0 : frameOffset.top; + const frameLeft = opts.avoidFrameOffset ? 0 : frameOffset.left; - const top = elRect.top * zoom + frameTop - canvasOffset.top + canvasEl.scrollTop; - const left = elRect.left * zoom + frameLeft - canvasOffset.left + canvasEl.scrollLeft; - const height = elRect.height * zoom; - const width = elRect.width * zoom; + const elTop = opts.avoidFrameZoom ? elRect.top : elRect.top * zoom; + const elLeft = opts.avoidFrameZoom ? elRect.left : elRect.left * zoom; + + const top = opts.avoidFrameOffset ? elTop : (elTop + frameTop - canvasOffset.top + canvasEl.scrollTop); + const left = opts.avoidFrameOffset ? elLeft : (elLeft + frameLeft - canvasOffset.left + canvasEl.scrollLeft); + const height = opts.avoidFrameZoom ? elRect.height : elRect.height * zoom; + const width = opts.avoidFrameZoom ? elRect.width : elRect.width * zoom; return { top, left, height, width, zoom, rect: elRect }; } diff --git a/src/utils/Resizer.ts b/src/utils/Resizer.ts index 9b22e7fb4..aec29f8e5 100644 --- a/src/utils/Resizer.ts +++ b/src/utils/Resizer.ts @@ -1,6 +1,7 @@ import { bindAll, isFunction, each } from 'underscore'; import { Position } from '../common'; import { on, off, normalizeFloat } from './mixins'; +import { ElementPosOpts } from '../canvas/view/CanvasView'; type RectDim = { t: number; @@ -409,7 +410,7 @@ export default class Resizer { * @param {Object} opts Custom options * @return {Object} */ - getElementPos(el: HTMLElement, opts = {}) { + getElementPos(el: HTMLElement, opts: ElementPosOpts = {}) { const { posFetcher } = this; return posFetcher ? posFetcher(el, opts) : getBoundingRect(el); } @@ -456,8 +457,8 @@ export default class Resizer { const resizer = this; const config = this.opts || {}; const mouseFetch = this.mousePosFetcher; - const attrName = 'data-' + config.prefix + 'handler'; - const rect = this.getElementPos(el!, { target: 'el' }); + const attrName = 'data-' + config.prefix + 'handler'; + const rect = this.getElementPos(el!, { avoidFrameZoom: true, avoidFrameOffset: true }); const parentRect = this.getElementPos(parentEl!); const target = e.target as HTMLElement; this.handlerAttr = target.getAttribute(attrName)!;