fix(stage): 组件添加粗一点的边框后resize操作 选中样式没有和组件本身对齐

fix #562
This commit is contained in:
roymondchen 2024-01-03 14:45:25 +08:00
parent 310c1c21ce
commit 783f7c3fc1
5 changed files with 36 additions and 11 deletions

View File

@ -429,11 +429,11 @@ export default class ActionManager extends EventEmitter {
?.on('update', (data: UpdateEventData) => { ?.on('update', (data: UpdateEventData) => {
this.emit('multi-update', data); this.emit('multi-update', data);
}) })
.on('change-to-select', async (id: Id) => { .on('change-to-select', async (id: Id, e: MouseEvent) => {
// 如果还在多选状态,不触发切换到单选 // 如果还在多选状态,不触发切换到单选
if (this.isMultiSelectStatus) return false; if (this.isMultiSelectStatus) return false;
const el = this.getTargetElement(id); const el = this.getTargetElement(id);
this.emit('change-to-select', el); this.emit('change-to-select', el, e);
}); });
return multiDr; return multiDr;

View File

@ -35,7 +35,7 @@ import MoveableHelper from 'moveable-helper';
import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, Mode, ZIndex } from './const'; import { DRAG_EL_ID_PREFIX, GHOST_EL_ID_PREFIX, Mode, ZIndex } from './const';
import TargetShadow from './TargetShadow'; import TargetShadow from './TargetShadow';
import { DragResizeHelperConfig, Rect, TargetElement } from './types'; import { DragResizeHelperConfig, Rect, TargetElement } from './types';
import { calcValueByFontsize, getAbsolutePosition, getMarginValue, getOffset } from './util'; import { calcValueByFontsize, getAbsolutePosition, getBorderWidth, getMarginValue, getOffset } from './util';
/** /**
* /moveable会抛出各种状态事件DragResizeHelper负责响应这些事件target和拖拽节点targetShadow进行修改 * /moveable会抛出各种状态事件DragResizeHelper负责响应这些事件target和拖拽节点targetShadow进行修改
@ -131,8 +131,10 @@ export default class DragResizeHelper {
this.target.style.top = `${this.frameSnapShot.top + beforeTranslate[1] - marginTop}px`; this.target.style.top = `${this.frameSnapShot.top + beforeTranslate[1] - marginTop}px`;
} }
this.target.style.width = `${width}px`; const { borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = getBorderWidth(this.target);
this.target.style.height = `${height}px`;
this.target.style.width = `${width + borderLeftWidth + borderRightWidth}px`;
this.target.style.height = `${height + borderTopWidth + borderBottomWidth}px`;
} }
public onDragStart(e: OnDragStart): void { public onDragStart(e: OnDragStart): void {
@ -294,8 +296,11 @@ export default class DragResizeHelper {
let left = calcValueByFontsize(doc, offset.left) - marginLeft; let left = calcValueByFontsize(doc, offset.left) - marginLeft;
let top = calcValueByFontsize(doc, offset.top) - marginTop; let top = calcValueByFontsize(doc, offset.top) - marginTop;
const width = calcValueByFontsize(doc, el.clientWidth);
const height = calcValueByFontsize(doc, el.clientHeight); const { borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = getBorderWidth(el);
const width = calcValueByFontsize(doc, el.clientWidth + borderLeftWidth + borderRightWidth);
const height = calcValueByFontsize(doc, el.clientHeight + borderTopWidth + borderBottomWidth);
let shadowEl = this.getShadowEl(); let shadowEl = this.getShadowEl();
const shadowEls = this.getShadowEls(); const shadowEls = this.getShadowEls();

View File

@ -357,10 +357,10 @@ export default class StageCore extends EventEmitter {
private initMulDrEvent(): void { private initMulDrEvent(): void {
this.actionManager this.actionManager
// 多选切换到单选 // 多选切换到单选
.on('change-to-select', (el: HTMLElement) => { .on('change-to-select', (el: HTMLElement, e: MouseEvent) => {
this.select(el); this.select(el);
// 先保证画布内完成渲染,再通知外部更新 // 先保证画布内完成渲染,再通知外部更新
setTimeout(() => this.emit('select', el)); setTimeout(() => this.emit('select', el, e));
}) })
.on('multi-update', (data: UpdateEventData) => { .on('multi-update', (data: UpdateEventData) => {
this.emit('update', data); this.emit('update', data);

View File

@ -128,7 +128,7 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
const { inputTarget, targets } = e; const { inputTarget, targets } = e;
// 如果有多个元素被选中,同时点击的元素在选中元素中的其中一项,可能是多选态切换为该元素的单选态,抛事件给上一层继续判断是否切换 // 如果有多个元素被选中,同时点击的元素在选中元素中的其中一项,可能是多选态切换为该元素的单选态,抛事件给上一层继续判断是否切换
if (targets.length > 1 && targets.includes(inputTarget)) { if (targets.length > 1 && targets.includes(inputTarget)) {
this.emit('change-to-select', inputTarget.id.replace(DRAG_EL_ID_PREFIX, '')); this.emit('change-to-select', inputTarget.id.replace(DRAG_EL_ID_PREFIX, ''), e.inputEvent);
} }
}); });
} }

View File

@ -57,7 +57,7 @@ export const getOffset = (el: Element): Offset => {
// 将蒙层占位节点覆盖在原节点上方 // 将蒙层占位节点覆盖在原节点上方
export const getTargetElStyle = (el: TargetElement, zIndex?: ZIndex) => { export const getTargetElStyle = (el: TargetElement, zIndex?: ZIndex) => {
const offset = getOffset(el); const offset = getOffset(el);
const { transform } = getComputedStyle(el); const { transform, border } = getComputedStyle(el);
return ` return `
position: absolute; position: absolute;
transform: ${transform}; transform: ${transform};
@ -65,6 +65,7 @@ export const getTargetElStyle = (el: TargetElement, zIndex?: ZIndex) => {
top: ${offset.top}px; top: ${offset.top}px;
width: ${el.clientWidth}px; width: ${el.clientWidth}px;
height: ${el.clientHeight}px; height: ${el.clientHeight}px;
border: ${border};
${typeof zIndex !== 'undefined' ? `z-index: ${zIndex};` : ''} ${typeof zIndex !== 'undefined' ? `z-index: ${zIndex};` : ''}
`; `;
}; };
@ -260,3 +261,22 @@ export const getMarginValue = (el: Element) => {
marginTop: marginTopValue, marginTop: marginTopValue,
}; };
}; };
export const getBorderWidth = (el: Element) => {
if (!el)
return {
borderLeftWidth: 0,
borderRightWidth: 0,
borderTopWidth: 0,
borderBottomWidth: 0,
};
const { borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = getComputedStyle(el);
return {
borderLeftWidth: parseFloat(borderLeftWidth) || 0,
borderRightWidth: parseFloat(borderRightWidth) || 0,
borderTopWidth: parseFloat(borderTopWidth) || 0,
borderBottomWidth: parseFloat(borderBottomWidth) || 0,
};
};