在vue中,使用JointJS 3.x创建节点并可以在节点上自定义HTML内容

首先需要在vue环境下安装 jointjs 和 jquery

npm install jquery --save
npm install jointjs

以下就是在vue中使用 jointjs 3.x 创建自定义html节点的代码, 以下代码可以在vue中正常运行

<template>
    <div id="paper-html-elements" ref="canvas"></div>
</template>

<script>
import $ from 'jquery';
import * as joint from 'jointjs';
window.joint = joint;

export default {
    data() {
        return {
            paper: null,
            customDivContent: '', // 自定义html内容的容器
        };
    },
    mounted() {
        this.init();
    },
    methods: {
        init() {
            let namespace = joint.shapes;
            let graph = new joint.dia.Graph({}, { cellNamespace: namespace });

            this.parper = new joint.dia.Paper({
                el: this.$refs.canvas, // 使用ref绑定页面上的div标签
                width: 650,
                height: 400,
                gridSize: 1,
                model: graph,
                cellViewNamespace: namespace,
            });

            joint.shapes.html = {};
            joint.shapes.html.Element = joint.shapes.basic.Rect.extend({
                defaults: joint.util.defaultsDeep(
                    {
                        type: 'html.Element',
                        attrs: {
                            rect: { stroke: 'none', 'fill-opacity': 0 },
                        },
                    },
                    joint.shapes.basic.Rect.prototype.defaults
                ),
            });

            joint.shapes.html.ElementView = joint.dia.ElementView.extend({
                // 设置v-html可以把自定义的实例写入
                template: `
                    <div class="html-element">
                        <div class="custom-div" v-html="customDivContent"></div>
                    </div>
                `,

                initialize() {
                    joint.dia.ElementView.prototype.initialize.apply(this, arguments);
                    this.$box = $(this.template); // 使用 jQuery 直接创建节点
                },
                render: function () {
                    joint.dia.ElementView.prototype.render.apply(this, arguments);
                    this.paper.$el.prepend(this.$box);
                    this.updateBox();
                    return this;
                },
                updateBox: function () {
                    var bbox = this.model.getBBox();
                    this.$box.find('.custom-div').html(this.model.get('customDivContent')); // 更新 customDiv 的内容
                    this.$box.css({
                        width: bbox.width,
                        height: bbox.height,
                        left: bbox.x,
                        top: bbox.y,
                        transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)',
                    });
                },
                removeBox: function (evt) {
                    this.$box.remove();
                },
            });

            var el1 = new joint.shapes.html.Element({
                position: { x: 80, y: 80 },
                size: { width: 170, height: 100 },
            });

            var el2 = new joint.shapes.html.Element({
                position: { x: 370, y: 160 },
                size: { width: 170, height: 100 },
            });

            // 设置 customDivContent 的值
            this.customDivContent = '<div>Your custom content here</div><div class="red">红色</div>';
            el1.set('customDivContent', this.customDivContent);

            this.customDivContent = '<div>Another custom content</div>';
            el2.set('customDivContent', this.customDivContent);

            graph.addCells([el1, el2]);
            
            // 创建 Link 并连接两个节点
            var link = new joint.dia.Link({
                source: { id: el1.id },
                target: { id: el2.id },
                attrs: {
                    '.marker-target': { d: 'M 10 0 L 0 5 L 10 10 z' },
                },
            });

            graph.addCell(link);

            el1.findView(this.parper).updateBox(); // 调用视图对象的 updateBox 方法
            el2.findView(this.parper).updateBox(); // 调用视图对象的 updateBox 方法

        },
    },
};
</script>

<style>
#paper-html-elements {
    position: relative;
    border: 1px solid gray;
    display: inline-block;
    background: transparent;
    overflow: hidden;
}
#paper-html-elements svg {
    background: transparent;
}
#paper-html-elements svg .link {
    z-index: 2;
}

.html-element {
    position: absolute;
    background: #3498DB;
    pointer-events: none;
    -webkit-user-select: none;
    border-radius: 4px;
    border: 2px solid #2980B9;
    box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
    box-sizing: border-box;
    z-index: 2;
}
.html-element div {
    pointer-events: auto;
}
.html-element .custom-div {
    margin: 0px;
    padding: 0px;
    width: 100%;
    height: 100%;
    background-color: #ECF0F1;
    border: 1px solid #BDC3C7;
}
.red { 
    width: 50px;
    height: 30px;
    background-color: red;
}
</style>

  • 15
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值