mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 10:27:44 +08:00
Feat:新增添加节点附加的前置和后置内容的实例化选项
This commit is contained in:
parent
e939b6132f
commit
706b2ee65d
@ -322,5 +322,9 @@ export const defaultOpt = {
|
||||
// 演示插件配置
|
||||
demonstrateConfig: null,
|
||||
// 移动节点到画布中心、回到根节点等操作时是否将缩放层级复位为100%
|
||||
resetScaleOnMoveNodeToCenter: false
|
||||
resetScaleOnMoveNodeToCenter: false,
|
||||
// 添加附加的节点前置内容,前置内容指和文本同一行的区域中的前置内容,不包括节点图片部分
|
||||
createNodePrefixContent: null,
|
||||
// 添加附加的节点后置内容,后置内容指和文本同一行的区域中的后置内容,不包括节点图片部分
|
||||
createNodePostfixContent: null
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import Style from './Style'
|
||||
import Shape from './Shape'
|
||||
import { G, ForeignObject, Rect } from '@svgdotjs/svg.js'
|
||||
import { G, Rect } from '@svgdotjs/svg.js'
|
||||
import nodeGeneralizationMethods from './nodeGeneralization'
|
||||
import nodeExpandBtnMethods from './nodeExpandBtn'
|
||||
import nodeCommandWrapsMethods from './nodeCommandWraps'
|
||||
@ -8,7 +8,7 @@ import nodeCreateContentsMethods from './nodeCreateContents'
|
||||
import nodeExpandBtnPlaceholderRectMethods from './nodeExpandBtnPlaceholderRect'
|
||||
import nodeCooperateMethods from './nodeCooperate'
|
||||
import { CONSTANTS } from '../../../constants/constant'
|
||||
import { copyNodeTree } from '../../../utils/index'
|
||||
import { copyNodeTree, createForeignObjectNode } from '../../../utils/index'
|
||||
|
||||
// 节点类
|
||||
class Node {
|
||||
@ -76,6 +76,8 @@ class Node {
|
||||
this.noteEl = null
|
||||
this.noteContentIsShow = false
|
||||
this._attachmentData = null
|
||||
this._prefixData = null
|
||||
this._postfixData = null
|
||||
this._expandBtn = null
|
||||
this._lastExpandBtnType = null
|
||||
this._showExpandBtn = false
|
||||
@ -182,7 +184,12 @@ class Node {
|
||||
// 创建节点的各个内容对象数据
|
||||
createNodeData() {
|
||||
// 自定义节点内容
|
||||
let { isUseCustomNodeContent, customCreateNodeContent } = this.mindMap.opt
|
||||
let {
|
||||
isUseCustomNodeContent,
|
||||
customCreateNodeContent,
|
||||
createNodePrefixContent,
|
||||
createNodePostfixContent
|
||||
} = this.mindMap.opt
|
||||
if (isUseCustomNodeContent && customCreateNodeContent) {
|
||||
this._customNodeContent = customCreateNodeContent(this)
|
||||
}
|
||||
@ -201,6 +208,12 @@ class Node {
|
||||
this._tagData = this.createTagNode()
|
||||
this._noteData = this.createNoteNode()
|
||||
this._attachmentData = this.createAttachmentNode()
|
||||
this._prefixData = createNodePrefixContent
|
||||
? createNodePrefixContent(this)
|
||||
: null
|
||||
this._postfixData = createNodePostfixContent
|
||||
? createNodePostfixContent(this)
|
||||
: null
|
||||
}
|
||||
|
||||
// 计算节点的宽高
|
||||
@ -237,6 +250,11 @@ class Node {
|
||||
this._rectInfo.imgContentWidth = imgContentWidth = this._imgData.width
|
||||
this._rectInfo.imgContentHeight = imgContentHeight = this._imgData.height
|
||||
}
|
||||
// 自定义前置内容
|
||||
if (this._prefixData) {
|
||||
textContentWidth += this._prefixData.width
|
||||
textContentHeight = Math.max(textContentHeight, this._prefixData.height)
|
||||
}
|
||||
// 图标
|
||||
if (this._iconData.length > 0) {
|
||||
textContentWidth += this._iconData.reduce((sum, cur) => {
|
||||
@ -277,6 +295,11 @@ class Node {
|
||||
this._attachmentData.height
|
||||
)
|
||||
}
|
||||
// 自定义后置内容
|
||||
if (this._postfixData) {
|
||||
textContentWidth += this._postfixData.width
|
||||
textContentHeight = Math.max(textContentHeight, this._postfixData.height)
|
||||
}
|
||||
// 文字内容部分的尺寸
|
||||
this._rectInfo.textContentWidth = textContentWidth
|
||||
this._rectInfo.textContentHeight = textContentHeight
|
||||
@ -337,10 +360,11 @@ class Node {
|
||||
}
|
||||
// 如果存在自定义节点内容,那么使用自定义节点内容
|
||||
if (this.isUseCustomNodeContent()) {
|
||||
let foreignObject = new ForeignObject()
|
||||
foreignObject.width(width)
|
||||
foreignObject.height(height)
|
||||
foreignObject.add(this._customNodeContent)
|
||||
const foreignObject = createForeignObjectNode({
|
||||
el: this._customNodeContent,
|
||||
width,
|
||||
height
|
||||
})
|
||||
this.group.add(foreignObject)
|
||||
addHoverNode()
|
||||
return
|
||||
@ -355,6 +379,19 @@ class Node {
|
||||
// 内容节点
|
||||
let textContentNested = new G()
|
||||
let textContentOffsetX = 0
|
||||
// 自定义前置内容
|
||||
if (this._prefixData) {
|
||||
const foreignObject = createForeignObjectNode({
|
||||
el: this._prefixData.el,
|
||||
width: this._prefixData.width,
|
||||
height: this._prefixData.height
|
||||
})
|
||||
foreignObject
|
||||
.x(textContentOffsetX)
|
||||
.y((this._rectInfo.textContentHeight - this._prefixData.height) / 2)
|
||||
textContentNested.add(foreignObject)
|
||||
textContentOffsetX += this._prefixData.width + textContentItemMargin
|
||||
}
|
||||
// icon
|
||||
let iconNested = new G()
|
||||
if (this._iconData && this._iconData.length > 0) {
|
||||
@ -375,7 +412,7 @@ class Node {
|
||||
this._textData.node.attr('data-offsetx', textContentOffsetX)
|
||||
// 修复safari浏览器节点存在图标时文字位置不正确的问题
|
||||
;(this._textData.nodeContent || this._textData.node)
|
||||
.x(-oldX)// 修复非富文本模式下同时存在图标和换行的文本时,被收起和展开时图标与文字距离会逐渐拉大的问题
|
||||
.x(-oldX) // 修复非富文本模式下同时存在图标和换行的文本时,被收起和展开时图标与文字距离会逐渐拉大的问题
|
||||
.x(textContentOffsetX)
|
||||
.y(0)
|
||||
textContentNested.add(this._textData.node)
|
||||
@ -419,6 +456,19 @@ class Node {
|
||||
textContentNested.add(this._attachmentData.node)
|
||||
textContentOffsetX += this._attachmentData.width
|
||||
}
|
||||
// 自定义后置内容
|
||||
if (this._postfixData) {
|
||||
const foreignObject = createForeignObjectNode({
|
||||
el: this._postfixData.el,
|
||||
width: this._postfixData.width,
|
||||
height: this._postfixData.height
|
||||
})
|
||||
foreignObject
|
||||
.x(textContentOffsetX)
|
||||
.y((this._rectInfo.textContentHeight - this._postfixData.height) / 2)
|
||||
textContentNested.add(foreignObject)
|
||||
textContentOffsetX += this._postfixData.width
|
||||
}
|
||||
// 文字内容整体
|
||||
textContentNested.translate(
|
||||
width / 2 - textContentNested.bbox().width / 2,
|
||||
|
||||
@ -4,20 +4,13 @@ import {
|
||||
removeHtmlStyle,
|
||||
addHtmlStyle,
|
||||
checkIsRichText,
|
||||
isUndef
|
||||
isUndef,
|
||||
createForeignObjectNode
|
||||
} from '../../../utils'
|
||||
import {
|
||||
Image as SVGImage,
|
||||
SVG,
|
||||
A,
|
||||
G,
|
||||
Rect,
|
||||
Text,
|
||||
ForeignObject
|
||||
} from '@svgdotjs/svg.js'
|
||||
import { Image as SVGImage, SVG, A, G, Rect, Text } from '@svgdotjs/svg.js'
|
||||
import iconsSvg from '../../../svg/icons'
|
||||
import { CONSTANTS } from '../../../constants/constant'
|
||||
import {defenseXSS} from "../../../utils/xss";
|
||||
import { defenseXSS } from '../../../utils/xss'
|
||||
|
||||
// 创建图片节点
|
||||
function createImgNode() {
|
||||
@ -151,10 +144,15 @@ function createRichTextNode() {
|
||||
}
|
||||
let html = `<div>${defenseXSS(this.getData('text'))}</div>`
|
||||
if (!this.mindMap.commonCaches.measureRichtextNodeTextSizeEl) {
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl = document.createElement('div')
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position = 'fixed'
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.left = '-999999px'
|
||||
this.mindMap.el.appendChild(this.mindMap.commonCaches.measureRichtextNodeTextSizeEl)
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl =
|
||||
document.createElement('div')
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.position =
|
||||
'fixed'
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl.style.left =
|
||||
'-999999px'
|
||||
this.mindMap.el.appendChild(
|
||||
this.mindMap.commonCaches.measureRichtextNodeTextSizeEl
|
||||
)
|
||||
}
|
||||
let div = this.mindMap.commonCaches.measureRichtextNodeTextSizeEl
|
||||
div.innerHTML = html
|
||||
@ -175,10 +173,11 @@ function createRichTextNode() {
|
||||
height = Math.ceil(height)
|
||||
g.attr('data-width', width)
|
||||
g.attr('data-height', height)
|
||||
let foreignObject = new ForeignObject()
|
||||
foreignObject.width(width)
|
||||
foreignObject.height(height)
|
||||
foreignObject.add(div.children[0])
|
||||
const foreignObject = createForeignObjectNode({
|
||||
el: div.children[0],
|
||||
width,
|
||||
height
|
||||
})
|
||||
g.add(foreignObject)
|
||||
return {
|
||||
node: g,
|
||||
@ -418,17 +417,21 @@ function getNoteContentPosition() {
|
||||
// 测量自定义节点内容元素的宽高
|
||||
function measureCustomNodeContentSize(content) {
|
||||
if (!this.mindMap.commonCaches.measureCustomNodeContentSizeEl) {
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl = document.createElement('div')
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl =
|
||||
document.createElement('div')
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl.style.cssText = `
|
||||
position: fixed;
|
||||
left: -99999px;
|
||||
top: -99999px;
|
||||
`
|
||||
this.mindMap.el.appendChild(this.mindMap.commonCaches.measureCustomNodeContentSizeEl)
|
||||
this.mindMap.el.appendChild(
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl
|
||||
)
|
||||
}
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl.innerHTML = ''
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl.appendChild(content)
|
||||
let rect = this.mindMap.commonCaches.measureCustomNodeContentSizeEl.getBoundingClientRect()
|
||||
let rect =
|
||||
this.mindMap.commonCaches.measureCustomNodeContentSizeEl.getBoundingClientRect()
|
||||
return {
|
||||
width: rect.width,
|
||||
height: rect.height
|
||||
|
||||
@ -1342,9 +1342,7 @@ export const handleGetSvgDataExtraContent = ({
|
||||
const { el, cssText, height } = res
|
||||
if (el instanceof HTMLElement) {
|
||||
el.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
|
||||
const foreignObject = new ForeignObject()
|
||||
foreignObject.height(height)
|
||||
foreignObject.add(el)
|
||||
const foreignObject = createForeignObjectNode({ el, height })
|
||||
callback(foreignObject, height)
|
||||
}
|
||||
if (cssText) {
|
||||
@ -1461,3 +1459,16 @@ export const exitFullScreen = () => {
|
||||
document.mozCancelFullScreen()
|
||||
}
|
||||
}
|
||||
|
||||
// 创建foreignObject节点
|
||||
export const createForeignObjectNode = ({ el, width, height }) => {
|
||||
const foreignObject = new ForeignObject()
|
||||
if (width !== undefined) {
|
||||
foreignObject.width(width)
|
||||
}
|
||||
if (height !== undefined) {
|
||||
foreignObject.height(height)
|
||||
}
|
||||
foreignObject.add(el)
|
||||
return foreignObject
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user