html2Canvas一些奇怪问题的解决

一、html2Canvas的使用

首先还是需要讲一下html2Canvas的简单使用,本案例为vue3中使用html2Canvas:

1.1 安装

npm install html2canvas

1.2 引入

import html2canvas from 'html2canvas'

1.3 导出

async function exportImage() {
    if (miniMapEl.value) {
        const canvasObj = await html2canvas(miniMapEl.value, {
            backgroundColor: null,
            scale: 1.5
        });
        const img = canvasObj.toDataURL('image/png');

        // 可以选择将图片作为下载链接
        const linkEl = document.createElement('a');
        linkEl.href = img;
        linkEl.setAttribute('download', 'export_mindmap.png');
        linkEl.click();
    }
}

二、问题集锦

2.1 带有滚动条的元素标签无法截全

可以看到上面截图是我的html,它是带有滚动条的,当使用html2Canvas截图,结果如下:

截图结果将会跟html中一致,滚动部分会被截断,非常地所见即所得。

解决方案:

解决方案并不是通过设置去解决的,而是另辟蹊径,在截图按钮按下时放弃滚动,将其宽高设置为内容的宽高来截图:

<div :style="{ height: isScreenshot ? 'auto' : '800px', width: isScreenshot ? `${width}px` : '100%'">
</div>

当点击截图按钮时将isScreenshot变为true:

async function onClickScreenshot() {
    isScreenshot.value = true
    await nextTick()

    // html2Canvas截图操作
    ...
    
    // 截完图记得把样式变回去
    isScreenshot.value = false
}

vue3中 await nextTick() 可以保证渲染样式完成后进行操作。

2.2 div背景色出现奇怪灰色

原始html渲染如下:

截图结果如下:

可以看到每个div外圈出现了莫名灰色区域,无法消除。

解决方案:

2.2.1 scale增大
const canvasObj = await html2canvas(miniMapEl.value, {
    backgroundColor: null,
    scale: 1.5
});

这个方案是测试时偶然发现的,具体原因不知。

2.2.2 动态样式

通过多次测试,发现是因为box-shadow导致的,因此可以通过在截图时关闭相应的标签box-shadow来解决:

<div class="node" :style="{ boxShadow: isScreenshot ? 'none' : '1px 1px 2px black' }"></div>

根据官方文档所说的,某些css样式html2Canvas是不支持的:

所以你用到了如上的css,尽量不要使用,如果非要用,可以与我一样,在截图时关闭,展示时开启,但会导致截图上无法展示相应的css。

2.2.3 强制添加阴影截图

虽然无法使用css样式阴影,但如果非要添加阴影并支持截图,其实可以使用其他方式实现。本案例推荐svg来添加阴影,如若使用svg,需要将svg或者需要添加的阴影的标签样式改为绝对坐标:

position: absolute;

 将阴影覆盖在相应的标签后方,即可实现阴影展示并且在截图后保持样式:

svg的样例代码:

<!--width height 画布或者标签的大小-->
<svg :width="width" :height="height" xmlns="http://www.w3.org/2000/svg">
    <defs>
        <filter id="f1" x="0" y="0" width="200%" height="200%">
            <feDropShadow dx="2" dy="2" stdDeviation="5" flood-color="rgb(138, 138, 138)" flood-opacity="0.6" />
        </filter>
    </defs>
    <!--x y 需要阴影的标签绝对坐标 elWidth elHeight 需要阴影的标签大小 elBorderEadius 需要阴影的标签若有圆角,改为圆角-->
    <rect :x="x" :y="y" :width="elWidth" :height="elHeight" stroke="none"
            stroke-width="0" fill="#000000" :rx="elBorderEadius" filter="url(#f1)" />
</svg>

 

三、总结

还有许多问题,还没遇到的在这篇文章就不阐述了,如若未来遇到,还会在这篇文章中继续更新。总的来说,html2Canvas使用起来非常简单,但问题也是不少,特别是看到生成的图片与预期不符,是非常糟心的,本文中通过动态css的开启与关闭其实可以解决非常多的问题,加以应用应该能获得预期效果。 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值