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) => {
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;
const el = this.getTargetElement(id);
this.emit('change-to-select', el);
this.emit('change-to-select', el, e);
});
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 TargetShadow from './TargetShadow';
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进行修改
@ -131,8 +131,10 @@ export default class DragResizeHelper {
this.target.style.top = `${this.frameSnapShot.top + beforeTranslate[1] - marginTop}px`;
}
this.target.style.width = `${width}px`;
this.target.style.height = `${height}px`;
const { borderLeftWidth, borderRightWidth, borderTopWidth, borderBottomWidth } = getBorderWidth(this.target);
this.target.style.width = `${width + borderLeftWidth + borderRightWidth}px`;
this.target.style.height = `${height + borderTopWidth + borderBottomWidth}px`;
}
public onDragStart(e: OnDragStart): void {
@ -294,8 +296,11 @@ export default class DragResizeHelper {
let left = calcValueByFontsize(doc, offset.left) - marginLeft;
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();
const shadowEls = this.getShadowEls();

View File

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

View File

@ -128,7 +128,7 @@ export default class StageMultiDragResize extends MoveableOptionsManager {
const { inputTarget, targets } = e;
// 如果有多个元素被选中,同时点击的元素在选中元素中的其中一项,可能是多选态切换为该元素的单选态,抛事件给上一层继续判断是否切换
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) => {
const offset = getOffset(el);
const { transform } = getComputedStyle(el);
const { transform, border } = getComputedStyle(el);
return `
position: absolute;
transform: ${transform};
@ -65,6 +65,7 @@ export const getTargetElStyle = (el: TargetElement, zIndex?: ZIndex) => {
top: ${offset.top}px;
width: ${el.clientWidth}px;
height: ${el.clientHeight}px;
border: ${border};
${typeof zIndex !== 'undefined' ? `z-index: ${zIndex};` : ''}
`;
};
@ -260,3 +261,22 @@ export const getMarginValue = (el: Element) => {
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,
};
};