le5le-com / meta2d.js

The meta2d.js is real-time data exchange and interactive web 2D engine. Developers are able to build Web SCADA, IoT, Digital twins and so on. Meta2d.js是一个实时数据响应和交互的2d引擎,可用于Web组态,物联网,数字孪生等场景。
http://2ds.le5le.com
MIT License
772 stars 244 forks source link

关于图形组合后图层变换失效的问题 #151

Closed ZCY1715 closed 1 year ago

ZCY1715 commented 1 year ago

20230326212718

ZCY1715 commented 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)
  })
}
SignDawn commented 1 year ago

你可以认为每一个单独的图元都是在一个独立的图层的,同理由于图层太多,我认为 up 和 down 的意义并不是很大,建议直接使用 top 或 bottom ,top 和 bottom 对组合图元也是有处理的。

ZCY1715 commented 1 year ago

主要是现在我的组件都是自己绘制的组合图元,当有多个组合图元重叠的时候必须一个一个置底置顶操作调整,直到达到想要的状态,很麻烦。 我的想法是可不可以在组合函数中就将里面的每个图元放置到同一层中,然后在 combine 图元中增加一个记录之前的图层状态的对象数据,当取消组合的时候再可以根据此还原。 我想应该还需要一个记录图层数量的控制器,保证图层始终是连续的

SignDawn commented 1 year ago
  1. 没有图层的概念,就像画画一样,后绘制的图元就会覆盖在先绘制的图元上。
  2. 绘制的先后顺序,取决于 meta2d.store.data.pens ,你更改它的顺序,就可以更改先后绘制关系(图片是特例)
ZCY1715 commented 1 year ago

我了解了,meta2d.store.data.pens 从前往后绘制。如果想解决这个问题,是否考虑采用二维数组,一维的顺序来表示图层。一开始可以将每一个画笔始为单独的图层

meta2d.store.data.pens = [pen1,pen2,pen3 ...]

// ->
meta2d.store.data.pens = [
    [pen1],
    [pen2,pen3],
    ...
]

这样单独图元和组合图元只需在一维上切换顺序,取消组合即将数组拆成若干数组

SignDawn commented 1 year ago

改动太大了,官方估计不会改。 组合下可能还有组合,二维数组是不行的

SignDawn commented 1 year ago

组合下,两个图元也是可能存在覆盖的,同理,你也可能会更改它们之间覆盖关系。 变动成二维数组,或者三维数组,甚至是多维数组,复杂度高,源码中的变化也是很大的。 你可以考虑自行处理下,data.pens 的顺序。

SignDawn commented 1 year ago

image 你也可以看看这个场景,两个正方形是一个组合,而矩形覆盖着其中的一个,按照你上次讲的二维数组,如何才能实现? 如果你期望更改源码,你可能需要给出一个良好的技术方案

ZCY1715 commented 1 year ago

image 你也可以看看这个场景,两个正方形是一个组合,而矩形覆盖着其中的一个,按照你上次讲的二维数组,如何才能实现? 如果你期望更改源码,你可能需要给出一个良好的技术方案

在 Adobe Illustrator,Edraw 等一些制图软件中可以看出,对于不同层次关系的图元组合的时候,他们的做法都是将低层次的图元层级提高到最高层图元同层级,我觉得可以参考一下。 QQ录屏20230331153317  640i

ZCY1715 commented 1 year ago

组合下,两个图元也是可能存在覆盖的,同理,你也可能会更改它们之间覆盖关系。 变动成二维数组,或者三维数组,甚至是多维数组,复杂度高,源码中的变化也是很大的。 你可以考虑自行处理下,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
}
SignDawn commented 1 year ago

image 你也可以看看这个场景,两个正方形是一个组合,而矩形覆盖着其中的一个,按照你上次讲的二维数组,如何才能实现? 如果你期望更改源码,你可能需要给出一个良好的技术方案

在 Adobe Illustrator,Edraw 等一些制图软件中可以看出,对于不同层次关系的图元组合的时候,他们的做法都是将低层次的图元层级提高到最高层图元同层级,我觉得可以参考一下。 QQ录屏20230331153317 640i QQ录屏20230331153317 640i

我想,我已经解释过了,如果用户期望展示一个像我展示的那种场景,你这个方案实现不了。 作为一个开源框架,新的改动尽可能不要破坏原有能够实现的效果。 而且你这个改动,我还是认为有点大了,破坏性有点强,这一版本官方估计不会考虑。

SignDawn commented 1 year ago

我建议你可以考虑实现类似一个 像官网一样的 结构 Tab 。 image 用一维数组的方式,v-for 展示非 combine 的全部 pen 画笔,实现拖拽效果,用来更改 meta2d.store.data.pens 的顺序,可以实现很便捷的更改覆盖的顺序。 如果你没有理解我的意思,我抽空看看能不能写个 DEMO

SignDawn commented 1 year ago

想到了一个点子,新创建一个方法 ,upByArea 该方法不再直接更改 data.pens 的顺序,先去计算与 该图元 存在位置上命中(重叠)的图元,如果有,移到它后面;否则按原逻辑。 这样的话,也比较符合,当存在覆盖时,用户期望更改层级来解决覆盖问题。

ZCY1715 commented 1 year ago

想到了一个点子,新创建一个方法 ,upByArea 该方法不再直接更改 data.pens 的顺序,先去计算与 该图元 存在位置上命中(重叠)的图元,如果有,移到它后面;否则按原逻辑。 这样的话,也比较符合,当存在覆盖时,用户期望更改层级来解决覆盖问题。

好的。我已经通过修改pens顺序使我的项目没有问题的。但还是期望更新!

SignDawn commented 1 year ago

upByArea 已经上到代码里了, downByArea 还没写,可以测测看,如果没问题的话,可以自行参照提个 pr 试试看。 downByArea ,有空我再更

ananzhusen commented 1 year ago

新版,对组合图元的上/下一个图层解决方案是,将组合图元中所有图元先移动到这些图元中最后(上一个图层)/最前(下一个图层)的一个图元附近,使他们相邻,并保证这些图元不更改原顺序,再整体上/下移一层。