anchor.ts 4.36 KB
import editorStyle from "../util/defaultStyle";
import {GraphStyle} from "@/utils/styles";

import {SingleShapeMixin} from "@/g6/g6";
import {Item} from "@/g6/g6";

Item.prototype.anchorDebounceTimer = null

Item.prototype.getShowAnchorPoints = function () {
    return [
        [0, -0.5],
        [-0.5, 0],
        [0, 0.5],
        [0.5, 0],
    ]
}

Item.prototype.showAnchor = function (graph) {
    if (!!this.anchorDebounceTimer) {
        clearTimeout(this.anchorDebounceTimer)
        this.anchorDebounceTimer = null
    }
    if (this.getType() !== 'node') {
        return
    }
    const group = this.getContainer()
    if (!group.anchorShapes) {
        group.anchorShapes = []
        group.keyShape = this
        const bbox = this.getBBox()

        this.getShowAnchorPoints().forEach((point, index) => {
            const anchor = createAnchor(index, {
                x: bbox.width * point[0],
                y: bbox.height * point[1]
            }, group);
            group.anchorShapes.push(anchor)
        })
    } else {
        group.anchorShapes.forEach(a => {
            a.show()
            a.toFront()
        })
    }
    graph.paint()
}

Item.prototype.hideAnchor = function (graph) {

    if (graph.get('onDragEdge') === true) {
        return
    }

    if (!!this.anchorDebounceTimer) {
        return;
    } else {
        this.anchorDebounceTimer = setTimeout(() => {
            try {
                if (this.getType() !== 'node') {
                    return
                }
                const group = this.getContainer()
                if (!group.anchorShapes) {
                    return;
                } else {
                    group.anchorShapes.forEach(a => a.hide())
                }
                this.anchorDebounceTimer = null
                graph.paint()
            } catch (e) {

            }
        }, 100)
    }
}

Item.prototype.clearAnchor = function () {
    try {
        const group = this.getContainer()
        if (!!group.anchorShapes && group.anchorShapes.length > 0) {
            group.anchorShapes.forEach(i => i.remove())
        }
    } catch (e) {
        // console.error(e)
    }
}

export function createAnchor(index, style, group) {
    const anchorContainer = group.addGroup();
    const anchor = new Item({
        type: 'anchor',
        group: anchorContainer,
        capture: false,
        index,
        isActived: false,
        model: {
            style: {
                ...style,
                ...GraphStyle.anchorStyle,
                cursor: editorStyle.cursor.hoverEffectiveAnchor,
            }
        },
    });
    anchor.index = index
    anchor.isAnchor = true;
    anchor.toFront();
    let hotpot;
    anchor.hideHotpot = function () {
        hotpot.remove()
    }
    anchor.showHotpot = function () {
        hotpot = anchorContainer.addShape('marker', {
            attrs: {
                ...style,
                ...GraphStyle.anchorHotsoptStyle
            }
        });
        hotpot.toFront();
        anchor.getKeyShape().toFront();
    };
    anchor.setActived = function () {
        anchor.update({style: {...GraphStyle.anchorPointHoverStyle}});
    };
    anchor.clearActived = function () {
        anchor.update({style: {...GraphStyle.anchorStyle}});
    };
    anchor.setHotspotActived = function (act) {
        hotpot &&
        (act ?
            hotpot.attr(GraphStyle.anchorHotsoptActivedStyle)
            : hotpot.attr(GraphStyle.anchorHotsoptStyle))
    };
    return anchorContainer;
};

export function registerAnchor(G6) {
    G6.Shape.registerFactory('anchor', {
        defaultShapeType: 'marker'
    });
    G6.Shape.registerAnchor('single-anchor', G6.Util.mix({}, SingleShapeMixin, {
        itemType: 'anchor',

        drawShape(cfg, group) {
            const shapeType = this.shapeType;
            const style = this.getShapeStyle(cfg);
            const shape = group.addShape(shapeType, {
                attrs: style
            });
            return shape;
        },

        setState(name, value, item) {
            if (name === 'active-anchor') {
                if (value) {
                    this.update({style: {...GraphStyle.anchorPointHoverStyle}}, item);
                } else {
                    this.update({style: {...GraphStyle.anchorStyle}}, item);
                }
            }
        }
    }));
    G6.Shape.registerAnchor('marker', {shapeType: 'marker'}, 'single-anchor');
}