Browse Source

Fix canvas scroll on component select from layers. Closes #5342

pull/5358/head
Artur Arseniev 3 years ago
parent
commit
d9c5ee9a7b
  1. 4
      src/canvas/types.ts
  2. 5
      src/canvas/view/CanvasView.ts
  3. 47
      src/dom_components/view/ComponentView.ts

4
src/canvas/types.ts

@ -6,7 +6,9 @@ export interface ToWorldOption {
toWorld?: boolean; toWorld?: boolean;
} }
export interface GetBoxRectOptions extends ToScreenOption {} export interface GetBoxRectOptions extends ToScreenOption {
local?: boolean;
}
/**{START_EVENTS}*/ /**{START_EVENTS}*/
export enum CanvasEvents { export enum CanvasEvents {

5
src/canvas/view/CanvasView.ts

@ -386,6 +386,11 @@ export default class CanvasView extends ModuleView<Canvas> {
height, height,
}; };
if (opts.local) {
boxRect.x = left;
boxRect.y = top;
}
return opts.toScreen ? this.getRectToScreen(boxRect) : boxRect; return opts.toScreen ? this.getRectToScreen(boxRect) : boxRect;
} }

47
src/dom_components/view/ComponentView.ts

@ -16,13 +16,6 @@ import ComponentsView from './ComponentsView';
type ClbObj = ReturnType<ComponentView['_clbObj']>; type ClbObj = ReturnType<ComponentView['_clbObj']>;
interface Rect {
top?: number;
left?: number;
bottom?: number;
right?: number;
}
export interface IComponentView extends ExtractMethods<ComponentView> {} export interface IComponentView extends ExtractMethods<ComponentView> {}
export default class ComponentView extends View</** export default class ComponentView extends View</**
@ -433,7 +426,7 @@ Component> {
* have to take in account offsetParent * have to take in account offsetParent
*/ */
getOffsetRect() { getOffsetRect() {
const rect: Rect = {}; const rect = { top: 0, left: 0, bottom: 0, right: 0 };
const target = this.el; const target = this.el;
let gtop = 0; let gtop = 0;
let gleft = 0; let gleft = 0;
@ -457,32 +450,38 @@ Component> {
return rect; return rect;
} }
isInViewport({ rect }: { rect?: Rect } = {}) { isInViewport() {
const { el } = this; const { el, em, frameView } = this;
const elDoc = el.ownerDocument; const canvasView = em.Canvas.getCanvasView();
const { body } = elDoc; const elRect = canvasView.getElBoxRect(el, { local: true });
const frameElement = elDoc.defaultView?.frameElement as HTMLIFrameElement; const frameEl = frameView.el;
const { top, left } = rect || this.getOffsetRect(); const frameH = frameEl.clientHeight;
const frame = this.frameView.getOffsetRect(); 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 ( return partiallyIn;
top! >= frame.scrollTop &&
left! >= frame.scrollLeft &&
top! <= frame.scrollBottom &&
left! <= frameElement?.offsetWidth + body.scrollLeft
);
} }
scrollIntoView(opts: { force?: boolean } & ScrollIntoViewOptions = {}) { scrollIntoView(opts: { force?: boolean } & ScrollIntoViewOptions = {}) {
const rect = this.getOffsetRect(); const isInViewport = this.isInViewport();
const isInViewport = this.isInViewport({ rect });
if (!isInViewport || opts.force) { if (!isInViewport || opts.force) {
const { el } = this; const { el } = this;
// PATCH: scrollIntoView won't work with multiple requests from iframes // PATCH: scrollIntoView won't work with multiple requests from iframes
if (opts.behavior !== 'smooth') { if (opts.behavior !== 'smooth') {
el.ownerDocument.defaultView?.scrollTo(0, rect.top!); const rect = this.getOffsetRect();
el.ownerDocument.defaultView?.scrollTo(0, rect.top);
} else { } else {
el.scrollIntoView({ el.scrollIntoView({
behavior: 'smooth', behavior: 'smooth',

Loading…
Cancel
Save