【JointJS】define 自定义元素时注意:calc 相对计算和 resize 设置元素大小

发布时间 2023-07-28 03:03:15作者: Himmelbleu

可能遇到的问题

由于官方文档全是英文,阅读起来比较困难,通过我的阅读,在 Custom Elements 这一章节中主要的问题就是以下几点:

  1. 什么是 define 函数,自定义时文档中的代码为什么要指定 standard.Rectangle
  2. define 的第二个参数中的 attrs 是什么?第三个参数 markup 是什么?
  3. width、height 中的 calc(w) 是什么意思?相对于谁计算?
  4. resize 对 calc 有什么影响?对 RectSVGElement 定义 height 和 width 为什么不生效?
  5. cellViewNamespace 是什么?

define 函数

Element.define(type [, defaultInstanceProperties, prototypeProperties, staticProperties])

定义 Element 中新的子类型,可以对现有的元素覆盖自定义。比如 define 函数第一个参数 type 是 standard.Rectangle ,那么在之后的 new joint.shapes.standard.Rectangle(); 定义矩形图形时都会运用新的矩形样式。

  1. defaultInstanceProperties:这是默认属性,自定义时对这里设置就是覆盖默认的属性。由于 JointJS 最终渲染的结果是 SVG,所以这里的属性可以参考 MDN 文档进行设置。文档中有非常多的属性可以设置。
  2. prototypeProperties:指定形状的标记。比如,Rectangle 图形下有 RectSVGElement 和 TextSVGElement 两个子元素,那么 prototypeProperties 中的值就是:
{
  markup: [
    {
      tagName: "rect",
      selector: "main"
    },
    {
      tagName: "text",
      selector: "label"
    }
  ]
}

tagName 指定的就是标签的类型,比如 TextSVGElement 就是 text。selector 指定的是 defaultInstanceProperties 定义的默认属性,在创建时不传递就使用这个默认值,否则就覆盖这个默认值,并运用新的属性。

定义 standard.Rectangle

官方文档中的案例定义的是 standard.Rectangle,意思是就是自定义我们自己的矩形,而不使用官方的内置的矩形,就是覆盖掉默认的矩形样式。

如果要定义其他的矩形,不覆盖内置的,可以写其他的命名空间,比如 examples.Rectangle。此时的 cellViewNamespace 中就会多出一个 key 名为 examples,其下有一个图形叫作 Rectangle。

attrs

attrs 就是一些符合 SVG 的属性,所有的可用属性查看 MDN 文档。也就是对这些图形进行设置,比如宽度、高度、x、y 等。

而这些属性针对的是哪些呢?就要用到 markup。

markup

在自定义时我们要添加 markup 属性。这个属性的意思是针对于我们在 attrs 中设置的属性,要运用到哪一个标签中的意思,比如:

joint.dia.Element.define(
  "standard.Rectangle",
  {
    attrs: {
      // 我们定义的 markup 中第一个对象 selector 同样也对应这里的 key。
      // body: {
      main: {
        width: "calc(w)",
        height: "calc(h)",
        strokeWidth: 2,
        stroke: "#000000",
        fill: "#FFFFFF"
      },
      label: {
        textVerticalAnchor: "middle",
        textAnchor: "middle",
        x: "calc(0.5*w)",
        y: "calc(0.5*h)",
        fontSize: 12,
        fill: "#333333"
      }
    }
  },
  {
    markup: [
      // 这个图形中有一个子元素 RectSVGELement,因此 tagName: "rect"。而 selector 的意思是在定义的图形中,当
      // 对的 RectSVGELement 设置自定义 attrs 时 rect.attr({body: {}}) 中这个 key 里面的属性会应用到
      // RectSVGELement 中。
      {
        tagName: "rect",
        // selector: "body"
        selector: "main"
      },
      {
        tagName: "text",
        selector: "label"
      }
    ]
  }
);

attrs.main 中的属性是设置给 markup 第一个 RectSVGElement 的,就是说,这些属性都会给这个 SVG 元素当作默认属性和值。selector 就和 attrs 中的 key 一致。markup 和 attrs 顺序上保持一致。

calc

abc

resize

abc

示例

abc