Feat:新增导出图片时添加自定义内容的实例化选项
This commit is contained in:
parent
b2d5a626c7
commit
f0c08c7953
@ -19,7 +19,8 @@ import {
|
|||||||
simpleDeepClone,
|
simpleDeepClone,
|
||||||
getType,
|
getType,
|
||||||
getObjectChangedProps,
|
getObjectChangedProps,
|
||||||
isUndef
|
isUndef,
|
||||||
|
handleGetSvgDataExtraContent
|
||||||
} from './src/utils'
|
} from './src/utils'
|
||||||
import defaultTheme, {
|
import defaultTheme, {
|
||||||
checkIsNodeSizeIndependenceConfig
|
checkIsNodeSizeIndependenceConfig
|
||||||
@ -414,7 +415,18 @@ class MindMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取svg数据
|
// 获取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 svg = this.svg
|
||||||
const draw = this.draw
|
const draw = this.draw
|
||||||
// 保存原始信息
|
// 保存原始信息
|
||||||
@ -427,8 +439,9 @@ class MindMap {
|
|||||||
// 获取变换后的位置尺寸信息,其实是getBoundingClientRect方法的包装方法
|
// 获取变换后的位置尺寸信息,其实是getBoundingClientRect方法的包装方法
|
||||||
const rect = draw.rbox()
|
const rect = draw.rbox()
|
||||||
// 内边距
|
// 内边距
|
||||||
|
const fixHeight = 0
|
||||||
rect.width += paddingX * 2
|
rect.width += paddingX * 2
|
||||||
rect.height += paddingY * 2
|
rect.height += paddingY * 2 + fixHeight + headerHeight + footerHeight
|
||||||
draw.translate(paddingX, paddingY)
|
draw.translate(paddingX, paddingY)
|
||||||
// 将svg设置为实际内容的宽高
|
// 将svg设置为实际内容的宽高
|
||||||
svg.size(rect.width, rect.height)
|
svg.size(rect.width, rect.height)
|
||||||
@ -466,7 +479,21 @@ class MindMap {
|
|||||||
this.watermark.isInExport = false
|
this.watermark.isInExport = false
|
||||||
}
|
}
|
||||||
// 添加必要的样式
|
// 添加必要的样式
|
||||||
clone.add(SVG(`<style>${cssContent}</style>`))
|
;[cssContent, ...cssTextList].forEach(s => {
|
||||||
|
clone.add(SVG(`<style>${s}</style>`))
|
||||||
|
})
|
||||||
|
// 附加内容
|
||||||
|
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对不上
|
// 修正defs里定义的元素的id,因为clone时defs里的元素的id会继续递增,导致和内容中引用的id对不上
|
||||||
const defs = svg.find('defs')
|
const defs = svg.find('defs')
|
||||||
const defs2 = clone.find('defs')
|
const defs2 = clone.find('defs')
|
||||||
|
|||||||
@ -294,8 +294,8 @@ export const defaultOpt = {
|
|||||||
beforeShortcutRun: null,
|
beforeShortcutRun: null,
|
||||||
// 彩虹线条配置,需要先注册RainbowLines插件
|
// 彩虹线条配置,需要先注册RainbowLines插件
|
||||||
rainbowLinesConfig: {
|
rainbowLinesConfig: {
|
||||||
open: false,// 是否开启彩虹线条
|
open: false, // 是否开启彩虹线条
|
||||||
colorsList: []// 自定义彩虹线条的颜色列表,如果不设置,会使用默认颜色列表
|
colorsList: [] // 自定义彩虹线条的颜色列表,如果不设置,会使用默认颜色列表
|
||||||
/*
|
/*
|
||||||
[
|
[
|
||||||
'rgb(255, 213, 73)',
|
'rgb(255, 213, 73)',
|
||||||
@ -307,5 +307,16 @@ export const defaultOpt = {
|
|||||||
'rgb(152, 132, 234)'
|
'rgb(152, 132, 234)'
|
||||||
]
|
]
|
||||||
*/
|
*/
|
||||||
}
|
},
|
||||||
|
// 导出png、svg、pdf时在头部和尾部添加自定义内容
|
||||||
|
// 可传递一个函数,这个函数需要返回如下数据:
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
el,// 要追加的自定义DOM节点,样式可内联
|
||||||
|
cssText,// 可选,如果样式不想内联,可以传递该值,一个css字符串
|
||||||
|
height: 50// 返回的DOM节点的高度,必须传递
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
addContentToHeader: null,
|
||||||
|
addContentToFooter: null
|
||||||
}
|
}
|
||||||
|
|||||||
@ -48,11 +48,13 @@ class Export {
|
|||||||
|
|
||||||
// 获取svg数据
|
// 获取svg数据
|
||||||
async getSvgData() {
|
async getSvgData() {
|
||||||
let { exportPaddingX, exportPaddingY, errorHandler, resetCss } =
|
let { exportPaddingX, exportPaddingY, errorHandler, resetCss, addContentToHeader, addContentToFooter } =
|
||||||
this.mindMap.opt
|
this.mindMap.opt
|
||||||
let { svg, svgHTML } = this.mindMap.getSvgData({
|
let { svg, svgHTML } = this.mindMap.getSvgData({
|
||||||
paddingX: exportPaddingX,
|
paddingX: exportPaddingX,
|
||||||
paddingY: exportPaddingY
|
paddingY: exportPaddingY,
|
||||||
|
addContentToHeader,
|
||||||
|
addContentToFooter
|
||||||
})
|
})
|
||||||
// svg的image标签,把图片的url转换成data:url类型,否则导出会丢失图片
|
// svg的image标签,把图片的url转换成data:url类型,否则导出会丢失图片
|
||||||
const task1 = this.createTransformImgTaskList(
|
const task1 = this.createTransformImgTaskList(
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import {
|
|||||||
selfCloseTagList
|
selfCloseTagList
|
||||||
} from '../constants/constant'
|
} from '../constants/constant'
|
||||||
import MersenneTwister from './mersenneTwister'
|
import MersenneTwister from './mersenneTwister'
|
||||||
|
import { ForeignObject } from '@svgdotjs/svg.js'
|
||||||
|
|
||||||
// 深度优先遍历树
|
// 深度优先遍历树
|
||||||
export const walk = (
|
export const walk = (
|
||||||
@ -1315,3 +1316,46 @@ export const getRectRelativePosition = (rect1, rect2) => {
|
|||||||
return 'overlap'
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user