借助html2canvas实现网页保存为图片
借助html2canvas实现网页保存为图片
html2canvas 能够实现在前端直接对页面进行截屏。其实现思路是html2canvas脚本将页面元素渲染为canvas,通过读取DOM并将不同的样式应用到这些元素上实现。它不需要服务端的操作,只在前端即可完成。
一. 在项目中的使用
1. 安装html2canvas
npm install --save html2canvas
2. 在项目中使用
// 在需要使用的页面中先引入html2canvas
import html2canvas from 'html2canvas'
然后在页面中使用,如下:
在template模板中,设置要生成图片的内容,本文中要生成图片的是ref="capture"的div,然后将生成的canvas图片展示在ref="addImage"的div中
<template>
<!-- 本文中要生成图片的是ref="capture"的div,然后将生成的canvas图片展示在ref="addImage"的div中 -->
<div class="content" ref="addImage">
<div ref="capture" class="image-content">
<div class="parent">
<img src="https://user-gold-cdn.xitu.io/2018/12/18/167c06ce8cf413d1?w=476&h=260&f=webp&s=11552">
</div>
<div class="parent">
<img src="https://user-gold-cdn.xitu.io/2018/12/18/167c06ce8d058da5?w=140&h=140&f=png&s=563">
</div>
<div class="parent">
<img src="https://user-gold-cdn.xitu.io/2018/12/18/167c06ce8da5216c?w=160&h=280&f=webp&s=10926">
</div>
<div class="parent">
<img src="https://img.alicdn.com/tps/i4/TB1hn3NMwHqK1RjSZFgSuu7JXXa.jpg_620x10000q100.jpg_.webp" alt>
</div>
</div>
<button @click="generatorImage" class="img-btn">生成图片</button>
</div>
</template>
然后在js文件中,generatorImage方法实现html到图片的转换,此时即可看到页面尾部已经添加了生成的图片内容,也可以对图片转为base64编码并下载到本地。
generatorImage () {
html2canvas(this.$refs.capture, { useCORS: true, backgroundColor: null }).then(canvas => {
this.$refs.addImage.append(canvas)
// 通过a标签下载到本地
let link = document.createElement('a')
link.href = canvas.toDataURL()
link.setAttribute('download', '图片canvas.png')
link.style.display = 'none'
document.body.appendChild(link)
link.click()
})
}
二. html2canvas存在跨域资源无法加载
如果要生成图片的dom元素中,包含有跨域资源,比如img标签中的跨域图片,通过上述方法生成的图片中,img的内容是空白的,无法生成,这是因为canvas对于图片资源的同源限制。
解决办法: html2canvas可以设置配置项,来实现图片的加载
1. allowTaint 设置成true,即可实现图片的展示(但是会导致无发下载)
allowTaint 为 true是允许canvas被污染,一旦画布污染,就无法读取其数据,不能使用画布的 toBolb(), toDataURL() 或 getImageData() 方法,否则会出错.
如果我们只是展示在页面上,不通过js转为文件下载到本地(下载需要调用canvas.toDataURL()方法),则可以使用该方法。(页面中右键可以将这张图片完好的保存到本地)
2. 通过服务器端设置CORS
解决跨域最常用的方法是跨域资源共享,我们将图片服务器的 response header 设置
access-control-allow-origin: *
即可解决跨域图片的访问,同时,配合html2canvas的配置项useCORS: true,即可实现canvas图片的转化和下载。
完整demo:
<template>
<!-- 本文中要生成图片的是ref="capture"的div,然后将生成的canvas图片展示在ref="addImage"的div中 -->
<div class="content" ref="addImage">
<div ref="capture" class="image-content">
<div class="parent">
<img src="https://user-gold-cdn.xitu.io/2018/12/18/167c06ce8cf413d1?w=476&h=260&f=webp&s=11552">
</div>
<div class="parent">
<img src="https://user-gold-cdn.xitu.io/2018/12/18/167c06ce8d058da5?w=140&h=140&f=png&s=563">
</div>
<div class="parent">
<img src="https://user-gold-cdn.xitu.io/2018/12/18/167c06ce8da5216c?w=160&h=280&f=webp&s=10926">
</div>
<div class="parent">
<img src="https://img.alicdn.com/tps/i4/TB1hn3NMwHqK1RjSZFgSuu7JXXa.jpg_620x10000q100.jpg_.webp" alt>
</div>
</div>
<el-button @click="generatorImage" type="primary" class="img-btn">生成图片</el-button>
</div>
</template>
<script>
import html2canvas from 'html2canvas'
export default {
methods: {
generatorImage () {
html2canvas(this.$refs.capture, { useCORS: true, backgroundColor: null }).then(canvas => {
this.$refs.addImage.append(canvas)
// 通过a标签下载到本地
let link = document.createElement('a')
link.href = canvas.toDataURL()
link.setAttribute('download', '图片canvas.png')
link.style.display = 'none'
document.body.appendChild(link)
link.click()
})
}
}
}
</script>
<style lang="scss" scoped>
.content {
.image-content {
display: flex;
flex-wrap: wrap;
max-width: 1200px;
padding: 20px 30px;
}
.parent {
flex: 1;
}
}
</style>
常见BUG
-
- 生成出来的图片有白色背景
在配置项里配置 backgroundColor: null 即可。
-
- 有图片显示不出来并有报错(一般是跨域的错)
这是最常见的一个bug,就是这个插件无法生成跨域了的图片
-
- 生成图片后会在原始DOM上覆盖而产生一个闪动的效果
先让生成的图片隐藏,等生成好以后再展示
- 4.经典版本(0.5.0)常见bug
1). 生成的图片模糊 2). 有跨域图片导致生成的图片不完整