mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2025-06-09 20:52:59 +08:00
feat(editor,stage): 多选支持居中操作
This commit is contained in:
parent
8f5acff0a6
commit
c949590f80
@ -118,10 +118,13 @@ watchEffect(() => {
|
|||||||
|
|
||||||
stage?.on('update', (ev: UpdateEventData) => {
|
stage?.on('update', (ev: UpdateEventData) => {
|
||||||
if (ev.parentEl) {
|
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;
|
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) => {
|
stage?.on('sort', (ev: SortEventData) => {
|
||||||
|
@ -34,10 +34,10 @@ const menuData = reactive<MenuItem[]>([
|
|||||||
{
|
{
|
||||||
type: 'button',
|
type: 'button',
|
||||||
text: '水平居中',
|
text: '水平居中',
|
||||||
display: () => canCenter.value && !props.isMultiSelect,
|
display: () => canCenter.value,
|
||||||
handler: () => {
|
handler: () => {
|
||||||
if (!node.value) return;
|
if (!nodes.value) return;
|
||||||
editorService?.alignCenter(node.value);
|
editorService?.alignCenter(nodes.value);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -64,11 +64,14 @@ class Editor extends BaseService {
|
|||||||
'select',
|
'select',
|
||||||
'doAdd',
|
'doAdd',
|
||||||
'add',
|
'add',
|
||||||
|
'doRemove',
|
||||||
'remove',
|
'remove',
|
||||||
|
'doUpdate',
|
||||||
'update',
|
'update',
|
||||||
'sort',
|
'sort',
|
||||||
'copy',
|
'copy',
|
||||||
'paste',
|
'paste',
|
||||||
|
'duAlignCenter',
|
||||||
'alignCenter',
|
'alignCenter',
|
||||||
'moveLayer',
|
'moveLayer',
|
||||||
'moveToContainer',
|
'moveToContainer',
|
||||||
@ -417,12 +420,7 @@ class Editor extends BaseService {
|
|||||||
this.emit('remove');
|
this.emit('remove');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public async doUpdate(config: MNode) {
|
||||||
* 更新节点
|
|
||||||
* @param config 新的节点配置,配置中需要有id信息
|
|
||||||
* @returns 更新后的节点配置
|
|
||||||
*/
|
|
||||||
public async update(config: MNode): Promise<MNode> {
|
|
||||||
if (!config?.id) throw new Error('没有配置或者配置缺少id值');
|
if (!config?.id) throw new Error('没有配置或者配置缺少id值');
|
||||||
|
|
||||||
const info = this.getNodeInfo(config.id, false);
|
const info = this.getNodeInfo(config.id, false);
|
||||||
@ -475,13 +473,27 @@ class Editor extends BaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.addModifiedNodeId(newConfig.id);
|
this.addModifiedNodeId(newConfig.id);
|
||||||
this.pushHistoryState();
|
|
||||||
|
|
||||||
this.emit('update', newConfig);
|
|
||||||
|
|
||||||
return 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]
|
* 将id为id1的组件移动到id为id2的组件位置上,例如:[1,2,3,4] -> sort(1,3) -> [2,1,3,4]
|
||||||
* @param id1 组件ID
|
* @param id1 组件ID
|
||||||
@ -533,15 +545,13 @@ class Editor extends BaseService {
|
|||||||
return this.add(pasteConfigs);
|
return this.add(pasteConfigs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
public async doAlignCenter(config: MNode): Promise<MNode> {
|
||||||
* 将指点节点设置居中
|
const parent = this.getParentById(config.id);
|
||||||
* @param config 组件节点配置
|
|
||||||
* @returns 当前组件节点配置
|
if (!parent) throw new Error('找不到父节点');
|
||||||
*/
|
|
||||||
public async alignCenter(config: MNode): Promise<MNode> {
|
|
||||||
const parent = this.get<MContainer>('parent');
|
|
||||||
const node = cloneDeep(toRaw(config));
|
const node = cloneDeep(toRaw(config));
|
||||||
const layout = await this.getLayout(toRaw(parent), node);
|
const layout = await this.getLayout(parent, node);
|
||||||
if (layout === Layout.RELATIVE) {
|
if (layout === Layout.RELATIVE) {
|
||||||
return config;
|
return config;
|
||||||
}
|
}
|
||||||
@ -561,12 +571,23 @@ class Editor extends BaseService {
|
|||||||
node.style.left = (parent.style.width - node.style.width) / 2;
|
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;
|
return newNode;
|
||||||
}
|
}
|
||||||
|
@ -450,9 +450,13 @@ export default class StageDragResize extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.emit('update', {
|
this.emit('update', {
|
||||||
el: this.target,
|
data: [
|
||||||
|
{
|
||||||
|
el: this.target,
|
||||||
|
style: isResize ? { left, top, width, height } : { left, top },
|
||||||
|
},
|
||||||
|
],
|
||||||
parentEl,
|
parentEl,
|
||||||
style: isResize ? { left, top, width, height } : { left, top },
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,16 +205,19 @@ export default class StageMultiDragResize extends EventEmitter {
|
|||||||
const doc = contentWindow?.document;
|
const doc = contentWindow?.document;
|
||||||
if (!doc) return;
|
if (!doc) return;
|
||||||
|
|
||||||
this.targetList.forEach((targetItem) => {
|
this.emit('update', {
|
||||||
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
|
data: this.targetList.map((targetItem) => {
|
||||||
const left = calcValueByFontsize(doc, offset.left);
|
const offset = { left: targetItem.offsetLeft, top: targetItem.offsetTop };
|
||||||
const top = calcValueByFontsize(doc, offset.top);
|
const left = calcValueByFontsize(doc, offset.left);
|
||||||
const width = calcValueByFontsize(doc, targetItem.clientWidth);
|
const top = calcValueByFontsize(doc, offset.top);
|
||||||
const height = calcValueByFontsize(doc, targetItem.clientHeight);
|
const width = calcValueByFontsize(doc, targetItem.clientWidth);
|
||||||
this.emit('update', {
|
const height = calcValueByFontsize(doc, targetItem.clientHeight);
|
||||||
el: targetItem,
|
return {
|
||||||
style: isResize ? { left, top, width, height } : { left, top },
|
el: targetItem,
|
||||||
});
|
style: isResize ? { left, top, width, height } : { left, top },
|
||||||
|
};
|
||||||
|
}),
|
||||||
|
parentEl: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -87,19 +87,21 @@ export interface GuidesEventData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface UpdateEventData {
|
export interface UpdateEventData {
|
||||||
el: HTMLElement;
|
data: {
|
||||||
parentEl: HTMLElement | null;
|
el: HTMLElement;
|
||||||
ghostEl: HTMLElement;
|
style: {
|
||||||
style: {
|
width?: number;
|
||||||
width?: number;
|
height?: number;
|
||||||
height?: number;
|
left?: number;
|
||||||
left?: number;
|
top?: number;
|
||||||
top?: number;
|
transform?: {
|
||||||
transform?: {
|
rotate?: string;
|
||||||
rotate?: string;
|
scale?: string;
|
||||||
scale?: string;
|
};
|
||||||
};
|
};
|
||||||
};
|
ghostEl?: HTMLElement;
|
||||||
|
}[];
|
||||||
|
parentEl: HTMLElement | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SortEventData {
|
export interface SortEventData {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user