mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-09-21 22:39:58 +08:00
fix(stage): 混合布局下拖动错乱
This commit is contained in:
parent
4560562553
commit
8e2d83fec9
@ -65,13 +65,12 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
*/
|
*/
|
||||||
public async select(el: HTMLElement, event?: MouseEvent): Promise<void> {
|
public async select(el: HTMLElement, event?: MouseEvent): Promise<void> {
|
||||||
this.target = el;
|
this.target = el;
|
||||||
|
this.target.style.overflow = 'hidden';
|
||||||
this.mode = getMode(el);
|
this.mode = getMode(el);
|
||||||
this.destroyDragEl();
|
this.destroyDragEl();
|
||||||
this.destroyGhostEl();
|
this.destroyGhostEl();
|
||||||
|
|
||||||
if (this.mode !== Mode.ABSOLUTE) {
|
this.dragEl = this.generateDragEl(el);
|
||||||
this.dragEl = this.generateDragEl(el);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.moveableOptions = await this.getOptions({
|
this.moveableOptions = await this.getOptions({
|
||||||
target: this.dragEl || this.target,
|
target: this.dragEl || this.target,
|
||||||
@ -151,31 +150,31 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on('resize', ({ width, height, drag }) => {
|
.on('resize', ({ width, height, drag }) => {
|
||||||
if (!this.moveable || !this.target) return;
|
if (!this.moveable || !this.target || !this.dragEl) return;
|
||||||
|
|
||||||
const { beforeTranslate } = drag;
|
const { beforeTranslate } = drag;
|
||||||
frame.translate = beforeTranslate;
|
frame.translate = beforeTranslate;
|
||||||
this.dragStatus = ActionStatus.ING;
|
this.dragStatus = ActionStatus.ING;
|
||||||
|
|
||||||
this.target.style.width = `${width}px`;
|
this.target.style.width = `${width}px`;
|
||||||
this.target.style.height = `${height}px`;
|
this.target.style.height = `${height}px`;
|
||||||
|
this.dragEl.style.width = `${width}px`;
|
||||||
|
this.dragEl.style.height = `${height}px`;
|
||||||
|
|
||||||
// 流式布局
|
// 流式布局
|
||||||
if (this.mode === Mode.SORTABLE && this.ghostEl) {
|
if (this.mode === Mode.SORTABLE) {
|
||||||
this.target.style.top = '0';
|
this.dragEl.style.top = `${beforeTranslate[1]}px`;
|
||||||
|
this.target.style.top = `0px`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.target.style.left = `${beforeTranslate[0]}px`;
|
this.dragEl.style.left = `${beforeTranslate[0]}px`;
|
||||||
this.target.style.top = `${beforeTranslate[1]}px`;
|
this.dragEl.style.top = `${beforeTranslate[1]}px`;
|
||||||
|
|
||||||
if (this.dragEl) {
|
const offset = getAbsolutePosition(this.target, { left: beforeTranslate[0], top: beforeTranslate[1] });
|
||||||
this.dragEl.style.width = `${width}px`;
|
|
||||||
this.dragEl.style.height = `${height}px`;
|
|
||||||
|
|
||||||
const offset = getAbsolutePosition(this.target, { left: beforeTranslate[0], top: beforeTranslate[1] });
|
this.target.style.left = `${offset.left}px`;
|
||||||
this.dragEl.style.left = `${offset.left}px`;
|
this.target.style.top = `${offset.top}px`;
|
||||||
this.dragEl.style.top = `${offset.top}px`;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.on('resizeEnd', () => {
|
.on('resizeEnd', () => {
|
||||||
this.dragStatus = ActionStatus.END;
|
this.dragStatus = ActionStatus.END;
|
||||||
@ -197,26 +196,23 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.on('drag', ({ left, top }) => {
|
.on('drag', ({ left, top }) => {
|
||||||
if (!this.target) return;
|
if (!this.target || !this.dragEl) return;
|
||||||
this.dragStatus = ActionStatus.ING;
|
this.dragStatus = ActionStatus.ING;
|
||||||
|
|
||||||
const offset = getAbsolutePosition(this.target, { left, top });
|
const offset = getAbsolutePosition(this.target, { left, top });
|
||||||
|
|
||||||
// 流式布局
|
// 流式布局
|
||||||
if (this.ghostEl && this.dragEl) {
|
if (this.ghostEl) {
|
||||||
this.dragEl.style.top = `${top}px`;
|
this.dragEl.style.top = `${top}px`;
|
||||||
this.ghostEl.style.top = `${offset.top}px`;
|
this.ghostEl.style.top = `${offset.top}px`;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 固定布局
|
this.dragEl.style.left = `${left}px`;
|
||||||
if (this.dragEl) {
|
this.dragEl.style.top = `${top}px`;
|
||||||
this.dragEl.style.left = `${left}px`;
|
|
||||||
this.dragEl.style.top = `${top}px`;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.target.style.left = `${left}px`;
|
this.target.style.left = `${offset.left}px`;
|
||||||
this.target.style.top = `${top}px`;
|
this.target.style.top = `${offset.top}px`;
|
||||||
})
|
})
|
||||||
.on('dragEnd', () => {
|
.on('dragEnd', () => {
|
||||||
// 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
|
// 点击不拖动时会触发dragStart和dragEnd,但是不会有drag事件
|
||||||
@ -312,12 +308,13 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
this.destroyDragEl();
|
this.destroyDragEl();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { left, top, width, height } = el.getBoundingClientRect();
|
const { width, height } = el.getBoundingClientRect();
|
||||||
|
const offset = getOffset(el);
|
||||||
const dragEl = globalThis.document.createElement('div');
|
const dragEl = globalThis.document.createElement('div');
|
||||||
dragEl.style.cssText = `
|
dragEl.style.cssText = `
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: ${left}px;
|
left: ${offset.left}px;
|
||||||
top: ${top}px;
|
top: ${offset.top}px;
|
||||||
width: ${width}px;
|
width: ${width}px;
|
||||||
height: ${height}px;
|
height: ${height}px;
|
||||||
`;
|
`;
|
||||||
@ -377,7 +374,7 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
|
|
||||||
if (fontSize) {
|
if (fontSize) {
|
||||||
const times = globalThis.parseFloat(fontSize) / 100;
|
const times = globalThis.parseFloat(fontSize) / 100;
|
||||||
return value / times;
|
return (value / times).toFixed(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
|
@ -20,7 +20,7 @@ import { Mode, MouseButton, ZIndex } from './const';
|
|||||||
import Rule from './Rule';
|
import Rule from './Rule';
|
||||||
import type StageCore from './StageCore';
|
import type StageCore from './StageCore';
|
||||||
import type { StageMaskConfig } from './types';
|
import type { StageMaskConfig } from './types';
|
||||||
import { createDiv, getScrollParent, isFixed } from './util';
|
import { createDiv, getScrollParent, isFixedParent } from './util';
|
||||||
|
|
||||||
const wrapperClassName = 'editor-mask-wrapper';
|
const wrapperClassName = 'editor-mask-wrapper';
|
||||||
|
|
||||||
@ -150,21 +150,7 @@ export default class StageMask extends Rule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public setLayout(el: HTMLElement): void {
|
public setLayout(el: HTMLElement): void {
|
||||||
let fixed = false;
|
this.setMode(isFixedParent(el) ? Mode.FIXED : Mode.ABSOLUTE);
|
||||||
let dom = el;
|
|
||||||
while (dom) {
|
|
||||||
fixed = isFixed(dom);
|
|
||||||
if (fixed) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const { parentElement } = dom;
|
|
||||||
if (!parentElement || parentElement.tagName === 'BODY') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
dom = parentElement;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setMode(fixed ? Mode.FIXED : Mode.ABSOLUTE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -108,8 +108,25 @@ export const isFixed = (el?: HTMLElement): boolean => {
|
|||||||
return getComputedStyle(el).position === 'fixed';
|
return getComputedStyle(el).position === 'fixed';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isFixedParent = (el: HTMLElement) => {
|
||||||
|
let fixed = false;
|
||||||
|
let dom = el;
|
||||||
|
while (dom) {
|
||||||
|
fixed = isFixed(dom);
|
||||||
|
if (fixed) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const { parentElement } = dom;
|
||||||
|
if (!parentElement || parentElement.tagName === 'BODY') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dom = parentElement;
|
||||||
|
}
|
||||||
|
return fixed;
|
||||||
|
};
|
||||||
|
|
||||||
export const getMode = (el: HTMLElement): Mode => {
|
export const getMode = (el: HTMLElement): Mode => {
|
||||||
if (isFixed(el)) return Mode.FIXED;
|
if (isFixedParent(el)) return Mode.FIXED;
|
||||||
if (isStatic(el) || isRelative(el)) return Mode.SORTABLE;
|
if (isStatic(el) || isRelative(el)) return Mode.SORTABLE;
|
||||||
return Mode.ABSOLUTE;
|
return Mode.ABSOLUTE;
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user