1、下载
yarn add dom-to-image
2、在 node_modules 文件夹中 找到 dom-to-image 文件夹里面的 dom-to-image.js 复制出来
3、 页面引入
import domtoimage from 'dom-to-image.js';
不修改也可以,我这边是因为使用了 阿里的oss,不能在后面加时间戳,所以修改
// 找到 文件中的 getAndEncode 方法,修改里面的 url
url += ((/\?/).test(url) ? "&" : "?")
1、domtoimage.toPng(…);将节点转化为png格式的图片
2、domtoimage.toJpeg(…);将节点转化为jpg格式的图片
3、domtoimage.toSvg(…);将节点转化为svg格式的图片,生成的图片的格式都是base64格式
4、domtoimage.toBlob(…);将节点转化为二进制格式,这个可以直接将图片下载
5、domtoimage.toPixelData(…);获取原始像素值,以Uint8Array 数组的形式返回,每4个数组元素表示一个像素点,即rgba值。这个方法也是挺实用的,可以用于WebGL中编写着色器颜色。
所有参数都可以不写,有默认的;
注意的是 `cacheBust` 参数,用于判断图片是否跨域
参数 | 说明 | 类型 |
filter | 过滤器节点中默写不需要的节点; | function |
bgcolor | 图片背景颜色; | string |
height, width | 图片宽高; | string |
style | 传入节点的样式,可以是任何有效的样式; | object |
quality | 图片的质量,也就是清晰度;一个介于 0 和 1 之间的数字,表示 JPEG 图像的图像质量(例如 0.92 => 92%)。默认为 1.0 (100%) | number |
cacheBust | 将时间戳加入到图片的url中,相当于添加新的图片; | Boolean |
imagePlaceholder | 图片生成失败时,在图片上面的提示,相当于img标签的alt; | string |
domtoimage.toPng(需要截图的元素,{ cacheBust: true }).then(function (dataUrl) {
//console.log(dataUrl)
})
.catch(function (error) {
console.error('生成失败', error);
});
domtoimage.toPng(toBlob,{
filter: (el) => {
// 过滤 VIDEO 标签
return !(el.tagName === 'VIDEO')
},
}).then(function (toBlob) {
console.log(toBlob)
})
// 1 、先把视频当前画面转成 canvas
const canvasBox = this.$refs.截图元素
/* 视频 (新增一个canvas 标签到同级) */
const canvasList = []
const videoElList = []
/* 找到元素下的所有 video 标签*/
const videoList = canvasBox.getElementsByTagName('video')
for (let i = 0; i < videoList.length; i++) {
const el = videoList[i]
if (el.tagName === 'VIDEO') {
var canvas = document.createElement('canvas')
var videoRatio = el.videoWidth / el.videoHeight;
var width = el.offsetWidth, height = el.offsetHeight;
var elementRatio = width / height;
if(elementRatio > videoRatio) {
width = height * videoRatio;
} else {
height = width / videoRatio;
}
canvas.width = width
canvas.height = height
canvas.className = 'juzhong'
canvas.style.cssText = el.style.cssText
const ctx = canvas.getContext('2d')
ctx.drawImage(el, 0, 0, width, height)
if (el.parentNode && el.parentNode.appendChild) {
el.parentNode.appendChild(canvas)
}
canvasList.push(canvas)
}
}
// 2、开始截图,过滤视频标签
domtoimage.toPng(canvasBox,{
filter: (el) => {
// 过滤 VIDEO 标签
return !(el.tagName === 'VIDEO')
},
}).then(function (dataUrl) {
/* 视频 (删除 替换的 canvas 标签) */
canvasList.forEach(el => {
el.parentNode.removeChild(el)
})
})
// 1、在 svgIcon.vue 组件中,新增一个 svgName
<svg :class="svgClass" aria-hidden="true" :svgName="svgName">
<use :xlink:href="iconName" />
</svg>
// 2、在截图元素中的 svg 插入内容
const canvasBox = this.$refs.截图元素
/* svg (找到 symbol 并移动到 svg 标签中) */
const symbolList = []
const svgList = canvasBox.getElementsByTagName('svg')
for (let i = 0; i < svgList.length; i++) {
const el = svgList[i]
if (el.id === '__SVG_SPRITE_NODE__') {
return
}
const svgName = el.getAttribute('svgName')
const item = document.getElementById(`icon-${svgName}`)
symbolList.push(item)
el.appendChild(item)
}
// 3、开始截图
domtoimage.toPng(canvasBox).then(function (dataUrl) {
/* svg (把获取的 symbol 移回去) */
const svgPublic = document.getElementById('__SVG_SPRITE_NODE__')
symbolList.forEach(el => {
svgPublic.appendChild(el)
})
})
// 找到 文件中的 getAndEncode 方法,修改里面的 url
url += ((/\?/).test(url) ? "&" : "?")
// 原本代码
return new Promise(function (resolve, reject) {
element.onload = resolve;
element.onerror = reject
element.src = dataUrl;
});
// 修改后
return new Promise(function (resolve, reject) {
element.onload = resolve;
element.onerror = (e) => {
// 不管怎么样都执行 resolve
resolve()
};
element.src = dataUrl;
});