diff --git a/src/canvas/view/CanvasView.ts b/src/canvas/view/CanvasView.ts index e34e6d609..ddb4ebd26 100644 --- a/src/canvas/view/CanvasView.ts +++ b/src/canvas/view/CanvasView.ts @@ -1,7 +1,7 @@ import { bindAll } from 'underscore'; import { ModuleView } from '../../abstract'; import { on, off, getElement, getKeyChar, isTextNode, getElRect, getUiClass } from '../../utils/mixins'; -import { createEl } from '../../utils/dom'; +import { createEl, getDocumentScroll } from '../../utils/dom'; import FramesView from './FramesView'; import Canvas from '../model/Canvas'; import FrameView from './FrameView'; @@ -19,7 +19,7 @@ export interface MarginPaddingOffsets { paddingLeft?: number; } -export type ElementPosOpts = { +export type ElementPosOpts = { avoidFrameOffset?: boolean; avoidFrameZoom?: boolean; noScroll?: boolean; @@ -199,13 +199,13 @@ export default class CanvasView extends ModuleView { * @return { {top: number, left: number, width: number, height: number} } */ offset(el?: HTMLElement, opts: ElementPosOpts = {}) { - const rect = getElRect(el); - const docBody = el?.ownerDocument.body; const { noScroll } = opts; + const rect = getElRect(el); + const scroll = noScroll ? { x: 0, y: 0 } : getDocumentScroll(el); return { - top: rect.top + (noScroll ? 0 : docBody?.scrollTop ?? 0), - left: rect.left + (noScroll ? 0 : docBody?.scrollLeft ?? 0), + top: rect.top + scroll.y, + left: rect.left + scroll.x, width: rect.width, height: rect.height, }; @@ -264,8 +264,8 @@ export default class CanvasView extends ModuleView { 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 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; diff --git a/src/commands/view/SelectComponent.ts b/src/commands/view/SelectComponent.ts index 770b39df4..c95105849 100644 --- a/src/commands/view/SelectComponent.ts +++ b/src/commands/view/SelectComponent.ts @@ -690,7 +690,7 @@ export default { * @private */ getElementPos(el: HTMLElement) { - return this.canvas.getCanvasView().getElementPos(el); + return this.canvas.getCanvasView().getElementPos(el, { noScroll: true }); }, /** diff --git a/src/utils/dom.ts b/src/utils/dom.ts index a1cac34e9..bfc8d9299 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -121,3 +121,17 @@ export const appendVNodes = (node: HTMLElement, vNodes: vNode | vNode[] = []) => node.appendChild(el); }); }; + +/** + * Get document scroll coordinates + */ +export const getDocumentScroll = (el?: HTMLElement) => { + const doc = el?.ownerDocument || document; + const docEl = doc.documentElement; + const win = doc.defaultView || window; + + return { + x: (win.pageXOffset || docEl.scrollLeft || 0) - (docEl.clientLeft || 0), + y: (win.pageYOffset || docEl.scrollTop || 0) - (docEl.clientTop || 0), + }; +};