本章主要实现素材的嵌套(生成阶段)这意味着可以拖入画布的对象,不只是图片素材,还可以是嵌套的图片和图形。在未来的章节中,应该可以实现素材成组/解散的效果。
最近难以抽出时间继续本示例更新,以至于拖到今天才更新这一章…
请大家动动小手,给我一个免费的 Star 吧~
大家如果发现了 Bug,欢迎来提 Issue 哟~
一些调整和优化
1、原本分散在各处的不同层的 draw 方法调用,现在基本上统一调用 render 的 redraw 方法,简化代码逻辑(暂未发现明显的性能问题)。
2、修复右键无法删除连接线的问题,主要是 stage 的 contextmenu 事件实测 target 无法得到指向的 Line 实例,目前使用 Konva.Util.haveIntersection 处理,以下是该逻辑的代码片段:
// src/Render/draws/ContextmenuDraw.ts
const linkGroup = this.render.layerCover.find(
`.${
Draws.LinkDraw.name}`
)[0] as Konva.Group
// 右键目标可能为 连接线
let lineSelection: Konva.Node | null = null
if (linkGroup) {
const linkLines = linkGroup.find('.link-line')
for (const line of linkLines) {
if (
Konva.Util.haveIntersection({
...pos, width: 1, height: 1 }, line.getClientRect())
) {
// 右键目标为 连接线
lineSelection = line
break
}
}
}
if (pos.x === this.state.lastPos.x || pos.y === this.state.lastPos.y) {
// 右键 连接线/其它目标
this.state.target = lineSelection ?? e.target
} else {
this.state.target = null
}
3、原来的对齐逻辑没有考虑目标被 rotate 后的情况,现已经修复支持了,实现方式还是使用三角函数计算:
红框是 rotate 后的占用区域,通过旋转角度就可以计算该区域的宽高,left、right、top、bottom 也是用于计算占用区域的 x,y 坐标:
// src/Render/tools/AlignTool.ts
calcNodeRotationInfo(node: Konva.Node) {
const rotate = node.rotation()
const offsetLeft = node.height() * Math.sin((rotate * Math.PI) / 180)
const offsetRight = node.width() * Math.cos((rotate * Math.PI) / 180)
const offsetTop = node.height() * Math.cos((rotate * Math.PI) / 180)
const offsetBottom = node.width() * Math.sin((rotate * Math.PI) / 180)
const width = Math.abs(offsetLeft) + Math.abs(offsetRight)
const height = Math.abs(offsetTop) + Math.abs(offsetBottom)
let x = node.x()
if ((rotate >= 0 && rotate < 90) || (rotate >= -360 && rotate < -270)) {
x = x - Math.abs(offsetLeft)
} else if ((rotate >= 90 && rotate < 180) || (rotate >= -270 && rotate < -180)) {
x = x - width
} else if ((rotate >= 180 && rotate < 270) || (rotate >= -180 && rotate < -90)) {
x = x - Math.abs(offsetRight)
} else if ((rotate >= 270 && rotate < 360) || (rotate >= -90 && rotate < 0)) {
// 无需处理
}
let y = node.y()
if ((rotate >= 0 && rotate < 90) || (rotate >= -360 && rotate < -270)) {
// 无需处理
} else if ((rotate >= 90 && rotate < 180