From 0979d2a779db58a3897f4bd0eda14eb0b77a2747 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Mon, 15 May 2023 15:25:40 +0400 Subject: [PATCH] Update getTargetToElementFixed --- src/canvas/index.ts | 57 ++++++++++++++++++----------------- src/canvas/view/CanvasView.ts | 12 ++++++-- src/common/index.ts | 7 +++++ 3 files changed, 46 insertions(+), 30 deletions(-) diff --git a/src/canvas/index.ts b/src/canvas/index.ts index c4734fe5b..ef0cf251f 100644 --- a/src/canvas/index.ts +++ b/src/canvas/index.ts @@ -402,10 +402,6 @@ export default class CanvasModule extends Module { const scroll = top ? scrollTop : scrollLeft; const offset = top ? offsetTop : offsetLeft; - // if (!top) { - // console.log('LEFT', { posLeft: pos[side], scroll, offset }, el); - // } - return pos[side] - (scroll - offset) * zoom; }; @@ -417,46 +413,51 @@ export default class CanvasModule extends Module { /** * - * @param {HTMLElement} el The element on which I'd attach the toolbar - * @param {HTMLElement} elToMove The target in this case could be the toolbar + * @param {HTMLElement} el The component element in the canvas + * @param {HTMLElement} targetEl The target element to position (eg. toolbar) * @param {Object} opts * @private */ - getTargetToElementFixed(el: HTMLElement, elToMove: HTMLElement, opts: any = {}) { - const pos = opts.pos || this.getElementPos(el, { noScroll: true }); - const cvOff = opts.canvasOff || this.canvasRectOffset(el, pos); - const toolbarH = elToMove.offsetHeight || 0; - const toolbarW = elToMove.offsetWidth || 0; - const elRight = pos.left + pos.width; - const cv = this.getCanvasView(); - const frCvOff = cv.getPosition(); - const frameOffset = cv.getFrameOffset(el); + getTargetToElementFixed(el: HTMLElement, targetEl: HTMLElement, opts: any = {}) { + const elRect = opts.pos || this.getElementPos(el, { noScroll: true }); + const canvasOffset = opts.canvasOff || this.canvasRectOffset(el, elRect); + const targetHeight = targetEl.offsetHeight || 0; + const targetWidth = targetEl.offsetWidth || 0; + const elRight = elRect.left + elRect.width; + const canvasView = this.getCanvasView(); + const canvasRect = canvasView.getPosition(); + const frameOffset = canvasView.getFrameOffset(el); const { event } = opts; - let top = -toolbarH; - let left = !isUndefined(opts.left) ? opts.left : pos.width - toolbarW; - left = pos.left < -left ? -pos.left : left; - const frCvWidth = frCvOff?.width ?? 0; - left = elRight > frCvWidth ? left - (elRight - frCvWidth) : left; + let top = -targetHeight; + let left = !isUndefined(opts.left) ? opts.left : elRect.width - targetWidth; + left = elRect.left < -left ? -elRect.left : left; + left = elRight > canvasRect.width ? left - (elRight - canvasRect.width) : left; - // Scroll with the window if the top edge is reached and the - // element is bigger than the canvas - const fullHeight = pos.height + toolbarH; - const elIsShort = fullHeight < frameOffset.height; + // Check when the target top edge reaches the top of the viewable canvas + if (canvasOffset.top < targetHeight) { + const fullHeight = elRect.height + targetHeight; + const elIsShort = fullHeight < frameOffset.height; - if (cvOff.top < toolbarH) { + // Scroll with the window if the top edge is reached and the + // element is bigger than the canvas if (elIsShort) { top = top + fullHeight; } else { - top = -cvOff.top < pos.height ? -cvOff.top : pos.height; + top = -canvasOffset.top < elRect.height ? -canvasOffset.top : elRect.height; } } const result = { top, left, - canvasOffsetTop: cvOff.top, - canvasOffsetLeft: cvOff.left, + canvasOffsetTop: canvasOffset.top, + canvasOffsetLeft: canvasOffset.left, + elRect, + canvasOffset, + canvasRect, + targetWidth, + targetHeight, }; // In this way I can catch data and also change the position strategy diff --git a/src/canvas/view/CanvasView.ts b/src/canvas/view/CanvasView.ts index ddb4ebd26..14e379ee4 100644 --- a/src/canvas/view/CanvasView.ts +++ b/src/canvas/view/CanvasView.ts @@ -7,6 +7,7 @@ import Canvas from '../model/Canvas'; import FrameView from './FrameView'; import ComponentView from '../../dom_components/view/ComponentView'; import Component from '../../dom_components/model/Component'; +import { ElementRect } from '../../common'; export interface MarginPaddingOffsets { marginTop?: number; @@ -304,9 +305,16 @@ export default class CanvasView extends ModuleView { * @return { {top: number, left: number, width: number, height: number} } obj Position object * @public */ - getPosition(opts: any = {}) { + getPosition(opts: any = {}): ElementRect { const doc = this.frame?.el.contentDocument; - if (!doc) return; + if (!doc) { + return { + top: 0, + left: 0, + width: 0, + height: 0, + }; + } const bEl = doc.body; const zoom = this.getZoom(); const fo = this.getFrameOffset(); diff --git a/src/common/index.ts b/src/common/index.ts index df4ff0e61..1f39b430b 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -22,6 +22,13 @@ export type Position = { y: number; }; +export type ElementRect = { + top: number; + left: number; + width: number; + height: number; +}; + export type CombinedModelConstructorOptions< E, M extends Model = Model