mirror of
https://github.com/wanglin2/mind-map.git
synced 2026-02-21 10:27:44 +08:00
Fix:修复思维导图非常大的情况下导出图片失败的问题
This commit is contained in:
parent
9ebc416167
commit
9f9ed1e84f
@ -318,6 +318,8 @@ export const defaultOpt = {
|
||||
// 导出png、svg、pdf时会获取画布上的svg数据进行克隆,然后通过该克隆的元素进行导出,如果你想对该克隆元素做一些处理,比如新增、替换、修改其中的一些元素,那么可以通过该参数传递一个处理函数,接收svg元素对象,处理后,需要返回原svg元素对象。
|
||||
// 需要注意的是svg对象指的是@svgdotjs/svg.js库的元素对象,所以你需要阅读该库的文档来操作该对象
|
||||
handleBeingExportSvg: null,
|
||||
// 导出图片或pdf都是通过canvas将svg绘制出来,再导出,所以如果思维导图特别大,宽高可能会超出canvas支持的上限,所以会进行缩放,这个上限可以通过该参数设置,代表canvas宽和高的最大宽度
|
||||
maxCanvasSize: 16384,
|
||||
|
||||
// 【AssociativeLine插件】
|
||||
// 关联线默认文字
|
||||
|
||||
@ -129,6 +129,7 @@ class Export {
|
||||
|
||||
// svg转png
|
||||
svgToPng(svgSrc, transparent, clipData = null) {
|
||||
const { maxCanvasSize, minExportImgCanvasScale } = this.mindMap.opt
|
||||
return new Promise((resolve, reject) => {
|
||||
const img = new Image()
|
||||
// 跨域图片需要添加这个属性,否则画布被污染了无法导出图片
|
||||
@ -136,10 +137,7 @@ class Export {
|
||||
img.onload = async () => {
|
||||
try {
|
||||
const canvas = document.createElement('canvas')
|
||||
const dpr = Math.max(
|
||||
window.devicePixelRatio,
|
||||
this.mindMap.opt.minExportImgCanvasScale
|
||||
)
|
||||
const dpr = Math.max(window.devicePixelRatio, minExportImgCanvasScale)
|
||||
let imgWidth = img.width
|
||||
let imgHeight = img.height
|
||||
// 如果是裁减操作的话,那么需要手动添加内边距,及调整图片大小为实际的裁减区域的大小,不要忘了内边距哦
|
||||
@ -152,29 +150,40 @@ class Export {
|
||||
imgHeight = clipData.height + paddingY * 2
|
||||
}
|
||||
// 检查是否超出canvas支持的像素上限
|
||||
const maxSize = 16384 / dpr
|
||||
const maxArea = maxSize * maxSize
|
||||
if (imgWidth * imgHeight > maxArea) {
|
||||
// canvas大小需要乘以dpr
|
||||
let canvasWidth = imgWidth * dpr
|
||||
let canvasHeight = imgHeight * dpr
|
||||
if (canvasWidth > maxCanvasSize || canvasHeight > maxCanvasSize) {
|
||||
let newWidth = null
|
||||
let newHeight = null
|
||||
if (imgWidth > maxSize) {
|
||||
newWidth = maxArea / imgHeight
|
||||
} else if (imgHeight > maxSize) {
|
||||
newHeight = maxArea / imgWidth
|
||||
if (canvasWidth > maxCanvasSize) {
|
||||
// 如果宽度超出限制,那么调整为上限值
|
||||
newWidth = maxCanvasSize
|
||||
} else if (canvasHeight > maxCanvasSize) {
|
||||
// 高度同理
|
||||
newHeight = maxCanvasSize
|
||||
}
|
||||
const res = resizeImgSize(imgWidth, imgHeight, newWidth, newHeight)
|
||||
imgWidth = res[0]
|
||||
imgHeight = res[1]
|
||||
// 计算缩放后的宽高
|
||||
const res = resizeImgSize(
|
||||
canvasWidth,
|
||||
canvasHeight,
|
||||
newWidth,
|
||||
newHeight
|
||||
)
|
||||
canvasWidth = res[0]
|
||||
canvasHeight = res[1]
|
||||
}
|
||||
canvas.width = imgWidth * dpr
|
||||
canvas.height = imgHeight * dpr
|
||||
canvas.style.width = imgWidth + 'px'
|
||||
canvas.style.height = imgHeight + 'px'
|
||||
canvas.width = canvasWidth
|
||||
canvas.height = canvasHeight
|
||||
const styleWidth = canvasWidth / dpr
|
||||
const styleHeight = canvasHeight / dpr
|
||||
canvas.style.width = styleWidth + 'px'
|
||||
canvas.style.height = styleHeight + 'px'
|
||||
const ctx = canvas.getContext('2d')
|
||||
ctx.scale(dpr, dpr)
|
||||
// 绘制背景
|
||||
if (!transparent) {
|
||||
await this.drawBackgroundToCanvas(ctx, imgWidth, imgHeight)
|
||||
await this.drawBackgroundToCanvas(ctx, styleWidth, styleHeight)
|
||||
}
|
||||
// 图片绘制到canvas里
|
||||
// 如果有裁减数据,那么需要进行裁减
|
||||
@ -191,7 +200,7 @@ class Export {
|
||||
clipData.height
|
||||
)
|
||||
} else {
|
||||
ctx.drawImage(img, 0, 0, imgWidth, imgHeight)
|
||||
ctx.drawImage(img, 0, 0, styleWidth, styleHeight)
|
||||
}
|
||||
resolve(canvas.toDataURL())
|
||||
} catch (error) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user