使用html-to-image前端生成分享海报
孙泽辉

今天完善一下浮墨笔记,实现分享memo功能,需要创建海报图片,用html-to-image完美解决问题。

仓库地址:bubkoo/html-to-image: ✂️ Generates an image from a DOM node using HTML5 canvas and SVG. (github.com)

实现

首先自己写好html,css就不展示了。。

1
2
3
4
5
6
7
8
9
<div class="memo">
<div class="content">
<span class="time">2022/09/09 09:30:32</span>
<span>
今天我吃饭了哈哈哈哈哈你好今天我吃饭了哈哈哈哈哈你好今天我吃饭了哈哈哈哈哈你好今天我吃饭了哈哈哈哈哈你好
</span>
</div>
<footer>✍️ by <b>sunzehui</b></footer>
</div>

我这里框架用的是vue3,在onMounted里拿到dom,然后生成图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import { onMounted } from 'vue'
// dom ref 方便获取 dom
const memoRef = ref(null);
// 图片链接,生成好的图片放到这里
const imgUrl = ref(null);
onMounted(async () => {
if (!show) return;
await nextTick();
const node = unref(memoRef);
if (!node) return;

// 转成 canvas 再转换 url
htmlToImage
.toCanvas(node, {
pixelRatio: window.devicePixelRatio * 2,
backgroundColor: "#eaeaea",
})
.then((canvas) => canvas.toDataURL())
.then((url) => {
imgUrl.value = url;
})
.catch(function (error) {
console.error("oops, something wents wrong!", error);
});
});

此时template里需绑定ref,并且添加展示图片的地方。

1
2
3
4
5
6
7
8
9
10
11
12
<!--> 给根元素添加 ref </-->
<div class="memo" ref="memoRef">
<!-- 此处图片绑定imgUrl变量 -->
<img :src="imgUrl" alt="img" v-if="imgUrl" class="absolute" />
<div class="content">
<span class="time">2022/09/09 09:30:32</span>
<span>
今天我吃饭了哈哈哈哈哈你好今天我吃饭了哈哈哈哈哈你好今天我吃饭了哈哈哈哈哈你好今天我吃饭了哈哈哈哈哈你好
</span>
</div>
<footer>✍️ by <b>sunzehui</b></footer>
</div>

img元素在海报未生成完成时不应插入到dom中所以使用v-if

为了方便展示,海报生成后立即覆盖原有dom层级显示,提示用户长按保存图片。

遇到的问题

图片模糊。

之前按照文档直接使用htmlToImage.toPng,生成的图片较为模糊,即使设置质量100%。

对比:

  1. 直接生成png
  1. 转换canvas后提取图片base64

效果

或许需要加个loading😐

  • Post title:使用html-to-image前端生成分享海报
  • Post author:孙泽辉
  • Create time:2022-09-09 15:07:04
  • Post link:https://hui.zone/post/3c284085.html
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.