JointJS如何在形状port端口内添加独立不重复的图片?
JointJS 矩形端口添加图片时主图重复问题解决方法
问题根因
这个重复问题是JointJS的SVG属性继承机制导致的:自定义portMarkup添加<image>标签时,如果没有给不同层级的image节点做选择器隔离,端口内的image节点会向上继承主元素上匹配到的image属性,包括图片源地址,最终渲染出和主矩形内部完全相同的重复图片。
具体修复方案
- 给两个图片节点设置完全独立的类名做选择器隔离
主形状内部的图片添加专属类名(例如main-inner-img),端口内部的图片添加不重名的专属类名(例如port-inner-img),从节点标识层面避免属性规则跨节点匹配。 - 绑定图片属性时使用专属类选择器,禁止用通用
image标签选择器赋值
不要在全局或者元素根层级直接给image标签设置xlink:href属性,分别在主元素属性块、端口组属性块里,给对应类名的image节点绑定各自的图片地址、尺寸、位置参数。
参考实现代码:const ImgPortRect = joint.dia.Element.define('shape.ImgPortRect', { size: { width: 140, height: 70 }, attrs: { // 矩形主体样式 '.rect-body': { width: 'calc(w)', height: 'calc(h)', fill: '#ffffff', stroke: '#2c3e50', 'stroke-width': 2, rx: 4 }, // 主形状内部图片,只匹配专属类 '.main-inner-img': { 'xlink:href': '/assets/first-pic.png', // 第一张图地址 width: 24, height: 24, x: 12, y: 'calc(0.5*h - 12)' } }, ports: { groups: { right: { position: 'right', attrs: { // 端口外框样式 '.port-outer': { r: 12, fill: '#ffffff', stroke: '#2c3e50', 'stroke-width': 2, magnet: true }, // 端口内部图片,只匹配专属类 '.port-inner-img': { 'xlink:href': '/assets/second-pic.png', // 第二张图地址 width: 14, height: 14, x: -7, y: -7 } } } } } }, { markup: joint.util.svg` <rect class="rect-body" @selector="rectBody"/> <image class="main-inner-img" @selector="mainInnerImg"/> `, portMarkup: joint.util.svg` <circle class="port-outer" @selector="portOuter"/> <image class="port-inner-img" @selector="portInnerImg"/> ` }); - 排查全局默认配置
检查项目中是否存在针对image标签的全局默认属性配置(例如在joint.dia.Element的全局默认attrs里给image设置了默认src),这类全局规则会匹配到所有层级的image节点,直接删除这类通用标签选择器的配置即可。
避坑提示:JointJS的属性匹配是沿SVG节点树向上冒泡查找的,只要选择器能同时匹配到主图和端口图两个节点,就会出现属性复用,类名唯一+类选择器赋值是最稳定的隔离方案,不需要修改框架源码。
内容的提问来源于stack exchange,提问作者User
相关产品推荐
相关产品推荐

