Closed ZCY1715 closed 1 year ago
我的想法是将遍历活跃的组合以及其子元件,全部都调用一遍 meta2d.up()
,但好像也不太行
const up = () => {
const idSet = new Set()
const allPens = []
let pens = [...store.value.active]
while (pens.length) {
const newIds = []
for (const pen of pens) {
if (!idSet.has(pen.id)) {
allPens.push(pen)
idSet.add(pen.id)
newIds.push(...(pen.children || []))
}
}
pens = newIds.map(id => store.value.pens[id])
}
allPens.forEach(pen => {
meta2d.value.up(pen)
})
}
你可以认为每一个单独的图元都是在一个独立的图层的,同理由于图层太多,我认为 up 和 down 的意义并不是很大,建议直接使用 top 或 bottom ,top 和 bottom 对组合图元也是有处理的。
主要是现在我的组件都是自己绘制的组合图元,当有多个组合图元重叠的时候必须一个一个置底置顶操作调整,直到达到想要的状态,很麻烦。 我的想法是可不可以在组合函数中就将里面的每个图元放置到同一层中,然后在 combine 图元中增加一个记录之前的图层状态的对象数据,当取消组合的时候再可以根据此还原。 我想应该还需要一个记录图层数量的控制器,保证图层始终是连续的
我了解了,meta2d.store.data.pens 从前往后绘制。如果想解决这个问题,是否考虑采用二维数组,一维的顺序来表示图层。一开始可以将每一个画笔始为单独的图层
meta2d.store.data.pens = [pen1,pen2,pen3 ...]
// ->
meta2d.store.data.pens = [
[pen1],
[pen2,pen3],
...
]
这样单独图元和组合图元只需在一维上切换顺序,取消组合即将数组拆成若干数组
改动太大了,官方估计不会改。 组合下可能还有组合,二维数组是不行的
组合下,两个图元也是可能存在覆盖的,同理,你也可能会更改它们之间覆盖关系。 变动成二维数组,或者三维数组,甚至是多维数组,复杂度高,源码中的变化也是很大的。 你可以考虑自行处理下,data.pens 的顺序。
你也可以看看这个场景,两个正方形是一个组合,而矩形覆盖着其中的一个,按照你上次讲的二维数组,如何才能实现? 如果你期望更改源码,你可能需要给出一个良好的技术方案
你也可以看看这个场景,两个正方形是一个组合,而矩形覆盖着其中的一个,按照你上次讲的二维数组,如何才能实现? 如果你期望更改源码,你可能需要给出一个良好的技术方案
在 Adobe Illustrator,Edraw 等一些制图软件中可以看出,对于不同层次关系的图元组合的时候,他们的做法都是将低层次的图元层级提高到最高层图元同层级,我觉得可以参考一下。
组合下,两个图元也是可能存在覆盖的,同理,你也可能会更改它们之间覆盖关系。 变动成二维数组,或者三维数组,甚至是多维数组,复杂度高,源码中的变化也是很大的。 你可以考虑自行处理下,data.pens 的顺序。
layerArr 数组中只需要存储图层中展示的单个图元或组合图元的 id,然后在用递归读取出绘制的顺序进行绘制?
// penMap: <id, Pen>
/*
组合图元
Pen {
id: "",
name: "combine",
children: [penId1, penId2, ...],
...
}
const layerArr = [
[id1],
[id2,id3, combineId1],
[combineId2, id4],
...
]
*/
function getSortPens(layerArr = []) {
const pens = layerArr.reduce((pens, arr) => {
const layerPens = arr.reduce((layerPens, curId) => {
layerPens.push(...getPensByParentId(curId))
return layerPens
}, [])
pens.push(...layerPens)
return pens
}, [])
// 变成 meta2d.store.data.pens 同样格式
}
function getPensByParentId(id) {
const pen = penMap.get(id)
const pens = [pen]
if (pen.name === "combine") {
const children = pen.children || []
children.forEach(childId => {
pens.push(...getPensByParentId(childId))
})
}
return pens
}
我建议你可以考虑实现类似一个 像官网一样的 结构 Tab 。 用一维数组的方式,v-for 展示非 combine 的全部 pen 画笔,实现拖拽效果,用来更改 meta2d.store.data.pens 的顺序,可以实现很便捷的更改覆盖的顺序。 如果你没有理解我的意思,我抽空看看能不能写个 DEMO
想到了一个点子,新创建一个方法 ,upByArea 该方法不再直接更改 data.pens 的顺序,先去计算与 该图元 存在位置上命中(重叠)的图元,如果有,移到它后面;否则按原逻辑。 这样的话,也比较符合,当存在覆盖时,用户期望更改层级来解决覆盖问题。
想到了一个点子,新创建一个方法 ,upByArea 该方法不再直接更改 data.pens 的顺序,先去计算与 该图元 存在位置上命中(重叠)的图元,如果有,移到它后面;否则按原逻辑。 这样的话,也比较符合,当存在覆盖时,用户期望更改层级来解决覆盖问题。
好的。我已经通过修改pens顺序使我的项目没有问题的。但还是期望更新!
upByArea 已经上到代码里了, downByArea 还没写,可以测测看,如果没问题的话,可以自行参照提个 pr 试试看。 downByArea ,有空我再更
新版,对组合图元的上/下一个图层解决方案是,将组合图元中所有图元先移动到这些图元中最后(上一个图层)/最前(下一个图层)的一个图元附近,使他们相邻,并保证这些图元不更改原顺序,再整体上/下移一层。