diff --git a/simple-mind-map/index.js b/simple-mind-map/index.js
index 48587f37..23db2ceb 100644
--- a/simple-mind-map/index.js
+++ b/simple-mind-map/index.js
@@ -19,7 +19,8 @@ import {
simpleDeepClone,
getType,
getObjectChangedProps,
- isUndef
+ isUndef,
+ handleGetSvgDataExtraContent
} from './src/utils'
import defaultTheme, {
checkIsNodeSizeIndependenceConfig
@@ -414,7 +415,18 @@ class MindMap {
}
// 获取svg数据
- getSvgData({ paddingX = 0, paddingY = 0, ignoreWatermark = false } = {}) {
+ getSvgData({
+ paddingX = 0,
+ paddingY = 0,
+ ignoreWatermark = false,
+ addContentToHeader,
+ addContentToFooter
+ } = {}) {
+ const { cssTextList, header, headerHeight, footer, footerHeight } =
+ handleGetSvgDataExtraContent({
+ addContentToHeader,
+ addContentToFooter
+ })
const svg = this.svg
const draw = this.draw
// 保存原始信息
@@ -427,8 +439,9 @@ class MindMap {
// 获取变换后的位置尺寸信息,其实是getBoundingClientRect方法的包装方法
const rect = draw.rbox()
// 内边距
+ const fixHeight = 0
rect.width += paddingX * 2
- rect.height += paddingY * 2
+ rect.height += paddingY * 2 + fixHeight + headerHeight + footerHeight
draw.translate(paddingX, paddingY)
// 将svg设置为实际内容的宽高
svg.size(rect.width, rect.height)
@@ -466,7 +479,21 @@ class MindMap {
this.watermark.isInExport = false
}
// 添加必要的样式
- clone.add(SVG(``))
+ ;[cssContent, ...cssTextList].forEach(s => {
+ clone.add(SVG(``))
+ })
+ // 附加内容
+ if (header && headerHeight > 0) {
+ clone.findOne('.smm-container').translate(0, headerHeight)
+ header.width(rect.width)
+ header.y(paddingY)
+ clone.add(header, 0)
+ }
+ if (footer && footerHeight > 0) {
+ footer.width(rect.width)
+ footer.y(rect.height - paddingY - footerHeight)
+ clone.add(footer)
+ }
// 修正defs里定义的元素的id,因为clone时defs里的元素的id会继续递增,导致和内容中引用的id对不上
const defs = svg.find('defs')
const defs2 = clone.find('defs')
diff --git a/simple-mind-map/src/constants/defaultOptions.js b/simple-mind-map/src/constants/defaultOptions.js
index fa1f8549..cab8da64 100644
--- a/simple-mind-map/src/constants/defaultOptions.js
+++ b/simple-mind-map/src/constants/defaultOptions.js
@@ -294,8 +294,8 @@ export const defaultOpt = {
beforeShortcutRun: null,
// 彩虹线条配置,需要先注册RainbowLines插件
rainbowLinesConfig: {
- open: false,// 是否开启彩虹线条
- colorsList: []// 自定义彩虹线条的颜色列表,如果不设置,会使用默认颜色列表
+ open: false, // 是否开启彩虹线条
+ colorsList: [] // 自定义彩虹线条的颜色列表,如果不设置,会使用默认颜色列表
/*
[
'rgb(255, 213, 73)',
@@ -307,5 +307,16 @@ export const defaultOpt = {
'rgb(152, 132, 234)'
]
*/
- }
+ },
+ // 导出png、svg、pdf时在头部和尾部添加自定义内容
+ // 可传递一个函数,这个函数需要返回如下数据:
+ /*
+ {
+ el,// 要追加的自定义DOM节点,样式可内联
+ cssText,// 可选,如果样式不想内联,可以传递该值,一个css字符串
+ height: 50// 返回的DOM节点的高度,必须传递
+ }
+ */
+ addContentToHeader: null,
+ addContentToFooter: null
}
diff --git a/simple-mind-map/src/plugins/Export.js b/simple-mind-map/src/plugins/Export.js
index a556e5fd..589ff89a 100644
--- a/simple-mind-map/src/plugins/Export.js
+++ b/simple-mind-map/src/plugins/Export.js
@@ -48,11 +48,13 @@ class Export {
// 获取svg数据
async getSvgData() {
- let { exportPaddingX, exportPaddingY, errorHandler, resetCss } =
+ let { exportPaddingX, exportPaddingY, errorHandler, resetCss, addContentToHeader, addContentToFooter } =
this.mindMap.opt
let { svg, svgHTML } = this.mindMap.getSvgData({
paddingX: exportPaddingX,
- paddingY: exportPaddingY
+ paddingY: exportPaddingY,
+ addContentToHeader,
+ addContentToFooter
})
// svg的image标签,把图片的url转换成data:url类型,否则导出会丢失图片
const task1 = this.createTransformImgTaskList(
diff --git a/simple-mind-map/src/utils/index.js b/simple-mind-map/src/utils/index.js
index 87292a59..d234d976 100644
--- a/simple-mind-map/src/utils/index.js
+++ b/simple-mind-map/src/utils/index.js
@@ -4,6 +4,7 @@ import {
selfCloseTagList
} from '../constants/constant'
import MersenneTwister from './mersenneTwister'
+import { ForeignObject } from '@svgdotjs/svg.js'
// 深度优先遍历树
export const walk = (
@@ -1315,3 +1316,46 @@ export const getRectRelativePosition = (rect1, rect2) => {
return 'overlap'
}
}
+
+// 处理获取svg内容时添加额外内容
+export const handleGetSvgDataExtraContent = ({
+ addContentToHeader,
+ addContentToFooter
+}) => {
+ // 追加内容
+ const cssTextList = []
+ let header = null
+ let headerHeight = 0
+ let footer = null
+ let footerHeight = 0
+ const handle = (fn, callback) => {
+ if (typeof fn === 'function') {
+ const { el, cssText, height } = fn()
+ if (el instanceof HTMLElement) {
+ el.setAttribute('xmlns', 'http://www.w3.org/1999/xhtml')
+ const foreignObject = new ForeignObject()
+ foreignObject.height(height)
+ foreignObject.add(el)
+ callback(foreignObject, height)
+ }
+ if (cssText) {
+ cssTextList.push(cssText)
+ }
+ }
+ }
+ handle(addContentToHeader, (foreignObject, height) => {
+ header = foreignObject
+ headerHeight = height
+ })
+ handle(addContentToFooter, (foreignObject, height) => {
+ footer = foreignObject
+ footerHeight = height
+ })
+ return {
+ cssTextList,
+ header,
+ headerHeight,
+ footer,
+ footerHeight
+ }
+}