请大家动动小手,给我一个免费的 Star 吧~
这一章处理一下复制、粘贴、删除、画布归位、层次调整,通过右键菜单控制。
复制粘贴
复制粘贴(通过快捷键)
// 复制暂存
pasteCache: Konva.Node[] = [];
// 粘贴次数(用于定义新节点的偏移距离)
pasteCount = 1;
// 复制
pasteStart() {
this.pasteCache = this.render.selectionTool.selectingNodes.map((o) => {
const copy = o.clone();
// 恢复透明度、可交互
copy.setAttrs({
listening: true,
opacity: copy.attrs.lastOpacity ?? 1,
});
// 清空状态
copy.setAttrs({
nodeMousedownPos: undefined,
lastOpacity: undefined,
lastZIndex: undefined,
selectingZIndex: undefined,
});
return copy;
});
this.pasteCount = 1;
}
// 粘贴
pasteEnd() {
if (this.pasteCache.length > 0) {
this.render.selectionTool.selectingClear();
this.copy(this.pasteCache);
this.pasteCount++;
}
}
快捷键处理:
keydown: (e: GlobalEventHandlersEventMap['keydown']) => {
if (e.ctrlKey) {
if (e.code === Types.ShutcutKey.C) {
this.render.copyTool.pasteStart() // 复制
} else if (e.code === Types.ShutcutKey.V) {
this.render.copyTool.pasteEnd() // 粘贴
}
}
}
}
逻辑比较简单,可以关注代码中的注释。
复制粘贴(右键)
/**
* 复制粘贴
* @param nodes 节点数组
* @param skip 跳过检查
* @returns 复制的元素
*/
copy(nodes: Konva.Node[]) {
const arr: Konva.Node[] = [];
for (const node of nodes) {
if (node instanceof Konva.Transformer) {
// 复制已选择
const backup = [...this.render.selectionTool.selectingNodes];
this.render.selectionTool.selectingClear();
this.copy(backup);
} else {
// 复制未选择
const copy = node.clone();
// 使新节点产生偏移
copy.setAttrs({
x: copy.x() + this.render.toStageValue(this.render.bgSize) * this.pasteCount,
y: copy.y() + this.render.toStageValue(this.render.bgSize) * this.pasteCount,
});
// 插入新节点
this.render.layer.add(copy);
// 选中复制内容
this.render.selectionTool.select([...this.render.selectionTool.selectingNodes, copy]);
}
}
return arr;
}
逻辑比较简单,可以关注代码中的注释。
删除
处理方法:
// 移除元素
remove(nodes: Konva.Node[]) {
for (const node of nodes) {
if (node instanceof Konva.Transformer) {
// 移除已选择的节点
this.remove(this.selectionTool.selectingNodes);
// 清除选择
this.selectionTool.selectingClear();
} else {
// 移除未选择的节点
node.remove();
}
}
}
事件处理:
keydown: (e: GlobalEventHandlersEventMap['keydown']) => {
if (e.ctrlKey) {
// 略
} else if (e.code === Types.ShutcutKey.删除) {
this.render.remove(this.render.selectionTool.selectingNodes)
}
}
画布归位
逻辑比较简单,恢复画布比例和偏移量:
// 恢复位置大小
positionZoomReset() {
this.render.stage.setAttrs({
scale: {
x: 1, y: 1 }
})