control.ts 4.43 KB
/*
 * @Date: 2023-10-27 09:29:59
 * @LastEditors: hookehuyr hookehuyr@gmail.com
 * @LastEditTime: 2023-11-14 15:31:33
 * @FilePath: /vue-flow-editor/src/shape/control.ts
 * @Description: 自定义控制节点
 */
import {BASE_COLOR} from "@/utils/styles";

// TAG: 自定义节点 - 定义节点
export function registerControl(G6) {
    G6.registerNode('control', {
        options: {
            style: {
            },
            stateStyles: {
            },
        },
        // 响应状态变化
        setState(name, value, item) {
            const group = item.getContainer();
            const shape = group.get('children')[0]; // 顺序根据 draw 时确定
            if (name === 'selected') {
                if (value) {
                    shape.attr('stroke', '#3A72F6');
                } else {
                    shape.attr('stroke', '');
                }
            }
            if (name === 'hover') {
                if (value) {
                    shape.attr('cursor', 'pointer');
                } else {
                    shape.attr('cursor', '');
                }
            }
        },
        getPath(cfg) {
            const size = cfg.size || [40, 40]; // 如果没有 size 时的默认大小
            const width = size[0];
            const height = size[1];
            //  / 1 \
            // 4     2
            //  \ 3 /
            const path = [
              ['M', 0, 0 - height / 2], // 上部顶点
              ['L', width / 2, 0], // 右侧顶点
              ['L', 0, height / 2], // 下部顶点
              ['L', -width / 2, 0], // 左侧顶点
              ['Z'], // 封闭
            ];
            return path;
        },
        drawShape(cfg, group) { // 继承了基类,可以使用drawShape,如果没有继承,必须要有draw

            let {text, desc, img, color} = cfg
            color = color || BASE_COLOR
            desc = desc || '无描述'

            const [width, height] = (cfg.size || [200, 80]) as [number, number]
            // 定义节点里的图形,名字和配置可以自定义
            const shapes = {
                keyShape: {
                    type: 'rect',
                    attrs: {fill: 'white', x: -width / 2, y: -height / 2, width, height, shadowColor: '#BFC5D2', shadowBlur: 50},
                },
                // 模拟一个菱形
                // keyShape: {
                //     type: 'path',
                //     attrs: {path: this.getPath(cfg),fill: 'white', x: -width / 2, y: -height / 2, width, height, shadowColor: '#BFC5D2', shadowBlur: 50},
                // },
                // sideRect: {
                //     type: 'rect',
                //     attrs: {x: -width / 2, y: -height / 2, width: 6, height, fill: color},
                // },
                img: {
                    type: 'image',
                    attrs: {x: height / 4 - width / 2, y: height / 4 - height / 2, width: height / 2, height: height / 2, img},
                },
                label: {
                    type: 'text',
                    attrs: {text, x: height - width / 2, y: height * (4 / 8) - height / 2, fontSize: 14, textAlign: 'left', textBaseline: 'middle', fill: 'black'},
                },
                // desc: {
                //     type: 'text',
                //     attrs: {text: desc, x: height - width / 2, y: height * (5 / 8) - height / 2, fontSize: 12, textAlign: 'left', textBaseline: 'middle', fill: '#999'},
                // },
            }

            const addShapes = {}

            let keyShape;
            Object.keys(shapes).forEach((shapeName) => {
                const {type, attrs} = shapes[shapeName]
                addShapes[shapeName] = group.addShape(type, {
                    attrs,
                    name: shapeName,
                    draggable: true,
                })

                if (shapeName === 'keyShape') {
                    keyShape = addShapes[shapeName]
                }
            })

            group.shapes = addShapes
            // 好像是必须返回一个名字叫keyShape,用于寻找节点
            return keyShape
        },
        update(cfg, group) {
            group = group.getContainer()
            // group.shapes.sideRect.attr({fill: cfg.color})
            group.shapes.img.attr({img: cfg.img})
            group.shapes.label.attr({text: cfg.text})
            // group.shapes.desc.attr({text: cfg.desc})
        },
    }, 'single-shape') // 继承了 single-shape 的基类
}