From d9c5ee9a7bd7b73a41fc2adee14a2646029d3945 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Wed, 30 Aug 2023 14:31:57 +0400 Subject: [PATCH] Fix canvas scroll on component select from layers. Closes #5342 --- src/canvas/types.ts | 4 +- src/canvas/view/CanvasView.ts | 5 +++ src/dom_components/view/ComponentView.ts | 47 ++++++++++++------------ 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/canvas/types.ts b/src/canvas/types.ts index 7f87c71653..e3112f6a9e 100644 --- a/src/canvas/types.ts +++ b/src/canvas/types.ts @@ -6,7 +6,9 @@ export interface ToWorldOption { toWorld?: boolean; } -export interface GetBoxRectOptions extends ToScreenOption {} +export interface GetBoxRectOptions extends ToScreenOption { + local?: boolean; +} /**{START_EVENTS}*/ export enum CanvasEvents { diff --git a/src/canvas/view/CanvasView.ts b/src/canvas/view/CanvasView.ts index 78fbf1a514..ce5f240acf 100644 --- a/src/canvas/view/CanvasView.ts +++ b/src/canvas/view/CanvasView.ts @@ -386,6 +386,11 @@ export default class CanvasView extends ModuleView { height, }; + if (opts.local) { + boxRect.x = left; + boxRect.y = top; + } + return opts.toScreen ? this.getRectToScreen(boxRect) : boxRect; } diff --git a/src/dom_components/view/ComponentView.ts b/src/dom_components/view/ComponentView.ts index 94426401f6..964b706565 100644 --- a/src/dom_components/view/ComponentView.ts +++ b/src/dom_components/view/ComponentView.ts @@ -16,13 +16,6 @@ import ComponentsView from './ComponentsView'; type ClbObj = ReturnType; -interface Rect { - top?: number; - left?: number; - bottom?: number; - right?: number; -} - export interface IComponentView extends ExtractMethods {} export default class ComponentView extends View { * have to take in account offsetParent */ getOffsetRect() { - const rect: Rect = {}; + const rect = { top: 0, left: 0, bottom: 0, right: 0 }; const target = this.el; let gtop = 0; let gleft = 0; @@ -457,32 +450,38 @@ Component> { return rect; } - isInViewport({ rect }: { rect?: Rect } = {}) { - const { el } = this; - const elDoc = el.ownerDocument; - const { body } = elDoc; - const frameElement = elDoc.defaultView?.frameElement as HTMLIFrameElement; - const { top, left } = rect || this.getOffsetRect(); - const frame = this.frameView.getOffsetRect(); + isInViewport() { + const { el, em, frameView } = this; + const canvasView = em.Canvas.getCanvasView(); + const elRect = canvasView.getElBoxRect(el, { local: true }); + const frameEl = frameView.el; + const frameH = frameEl.clientHeight; + const frameW = frameEl.clientWidth; + + const elTop = elRect.y; + const elRight = elRect.x; + const elBottom = elTop + elRect.height; + const elLeft = elRight + elRect.width; + const isTopInside = elTop >= 0 && elTop < frameH; + const isBottomInside = elBottom > 0 && elBottom < frameH; + const isLeftInside = elLeft >= 0 && elLeft < frameW; + const isRightInside = elRight > 0 && elRight <= frameW; + + const partiallyIn = (isTopInside || isBottomInside) && (isLeftInside || isRightInside); - return ( - top! >= frame.scrollTop && - left! >= frame.scrollLeft && - top! <= frame.scrollBottom && - left! <= frameElement?.offsetWidth + body.scrollLeft - ); + return partiallyIn; } scrollIntoView(opts: { force?: boolean } & ScrollIntoViewOptions = {}) { - const rect = this.getOffsetRect(); - const isInViewport = this.isInViewport({ rect }); + const isInViewport = this.isInViewport(); if (!isInViewport || opts.force) { const { el } = this; // PATCH: scrollIntoView won't work with multiple requests from iframes if (opts.behavior !== 'smooth') { - el.ownerDocument.defaultView?.scrollTo(0, rect.top!); + const rect = this.getOffsetRect(); + el.ownerDocument.defaultView?.scrollTo(0, rect.top); } else { el.scrollIntoView({ behavior: 'smooth',