feat(editor,stage): 多选支持居中操作

This commit is contained in:
roymondchen 2022-08-12 13:38:02 +08:00 committed by jia000
parent 8f5acff0a6
commit c949590f80
6 changed files with 84 additions and 51 deletions

View File

@ -118,10 +118,13 @@ watchEffect(() => {
stage?.on('update', (ev: UpdateEventData) => {
if (ev.parentEl) {
services?.editorService.moveToContainer({ id: ev.el.id, style: ev.style }, ev.parentEl.id);
for (const data of ev.data) {
services?.editorService.moveToContainer({ id: data.el.id, style: data.style }, ev.parentEl.id);
}
return;
}
services?.editorService.update({ id: ev.el.id, style: ev.style });
services?.editorService.update(ev.data.map((data) => ({ id: data.el.id, style: data.style })));
});
stage?.on('sort', (ev: SortEventData) => {

View File

@ -34,10 +34,10 @@ const menuData = reactive<MenuItem[]>([
{
type: 'button',
text: '水平居中',
display: () => canCenter.value && !props.isMultiSelect,
display: () => canCenter.value,
handler: () => {
if (!node.value) return;
editorService?.alignCenter(node.value);
if (!nodes.value) return;
editorService?.alignCenter(nodes.value);
},
},
{

View File

@ -64,11 +64,14 @@ class Editor extends BaseService {
'select',
'doAdd',
'add',
'doRemove',
'remove',
'doUpdate',
'update',
'sort',
'copy',
'paste',
'duAlignCenter',
'alignCenter',
'moveLayer',
'moveToContainer',
@ -417,12 +420,7 @@ class Editor extends BaseService {
this.emit('remove');
}
/**
*
* @param config id信息
* @returns
*/
public async update(config: MNode): Promise<MNode> {
public async doUpdate(config: MNode) {
if (!config?.id) throw new Error('没有配置或者配置缺少id值');
const info = this.getNodeInfo(config.id, false);
@ -475,13 +473,27 @@ class Editor extends BaseService {
}
this.addModifiedNodeId(newConfig.id);
this.pushHistoryState();
this.emit('update', newConfig);
return newConfig;
}
/**
*
* @param config id信息
* @returns
*/
public async update(config: MNode | MNode[]): Promise<MNode | MNode[]> {
const nodes = Array.isArray(config) ? config : [config];
const newNodes = await Promise.all(nodes.map((node) => this.doUpdate(node)));
this.pushHistoryState();
this.emit('update', newNodes);
return newNodes.length > 1 ? newNodes[0] : newNodes;
}
/**
* id为id1的组件移动到id为id2的组件位置上[1,2,3,4] -> sort(1,3) -> [2,1,3,4]
* @param id1 ID
@ -533,15 +545,13 @@ class Editor extends BaseService {
return this.add(pasteConfigs);
}
/**
*
* @param config
* @returns
*/
public async alignCenter(config: MNode): Promise<MNode> {
const parent = this.get<MContainer>('parent');
public async doAlignCenter(config: MNode): Promise<MNode> {
const parent = this.getParentById(config.id);
if (!parent) throw new Error('找不到父节点');
const node = cloneDeep(toRaw(config));
const layout = await this.getLayout(toRaw(parent), node);
const layout = await this.getLayout(parent, node);
if (layout === Layout.RELATIVE) {
return config;
}
@ -561,12 +571,23 @@ class Editor extends BaseService {
node.style.left = (parent.style.width - node.style.width) / 2;
}
const newNode = await this.update(node);
return node;
}
this.get<StageCore | null>('stage')?.update({
config: cloneDeep(toRaw(newNode)),
root: cloneDeep(this.get<MApp>('root')),
});
/**
*
* @param config
* @returns
*/
public async alignCenter(config: MNode | MNode[]): Promise<MNode | MNode[]> {
const nodes = Array.isArray(config) ? config : [config];
const stage = this.get<StageCore | null>('stage');
const newNodes = await Promise.all(nodes.map((node) => this.doAlignCenter(node)));
const newNode = await this.update(newNodes);
await stage?.multiSelect(newNodes.map((node) => node.id));
return newNode;
}

View File

@ -450,9 +450,13 @@ export default class StageDragResize extends EventEmitter {
}
this.emit('update', {
data: [
{
el: this.target,
parentEl,
style: isResize ? { left, top, width, height } : { left, top },
},
],
parentEl,
});
}

View File

@ -205,16 +205,19 @@ export default class StageMultiDragResize extends EventEmitter {
const doc = contentWindow?.document;
if (!doc) return;
this.targetList.forEach((targetItem) => {
this.emit('update', {
data: this.targetList.map((targetItem) => {
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
const left = calcValueByFontsize(doc, offset.left);
const top = calcValueByFontsize(doc, offset.top);
const width = calcValueByFontsize(doc, targetItem.clientWidth);
const height = calcValueByFontsize(doc, targetItem.clientHeight);
this.emit('update', {
return {
el: targetItem,
style: isResize ? { left, top, width, height } : { left, top },
});
};
}),
parentEl: null,
});
}

View File

@ -87,9 +87,8 @@ export interface GuidesEventData {
}
export interface UpdateEventData {
data: {
el: HTMLElement;
parentEl: HTMLElement | null;
ghostEl: HTMLElement;
style: {
width?: number;
height?: number;
@ -100,6 +99,9 @@ export interface UpdateEventData {
scale?: string;
};
};
ghostEl?: HTMLElement;
}[];
parentEl: HTMLElement | null;
}
export interface SortEventData {