canvas参考:https://blog.csdn.net/u012468376/article/details/73350998?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163642386816780261954825%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163642386816780261954825&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-73350998.first_rank_v2_pc_rank_v29&utm_term=canvas&spm=1018.2226.3001.4187
domtoimage参考文档:
domToImage 中文文档
实现思路:
简单版:(单个图不叠加不使用canvas)
dom-to-image 是一个JS类库,它可以将任意DOM节点转换成 SVG/PNG/JPEG 格式的图像。所以我们将想要截图区域的全部节点(给整个大节点加个ref='mynode',通过this.$refs.mynode取到节点)放进参数,会得到一个带有 dataUrls 的 promise。然后生成一个 Blob 格式的 PNG 图片,并下载它
代码如下:
function jietu(){
const node = this.$refs.map.$el //获取截图区域的节点,map是我的节点的ref的名称
domtoimage.toBlob(node) //生成一个 Blob 格式的 PNG 图片,并下载它
.then(function (blob) {
window.saveAs(blob, 'my-node.png');
});
}
进阶版:使用canvas实现截图(单层)
function jietu(){
const node = this.$refs.map.$el //获取截图区域的节点,map是我的节点的ref的名称
domtoimage.toPng(node)
.then(dataUrl => {
var img = new Image(); // 创建一个元素
img.src = dataUrl; // 设置图片源地址
img.onload = () => {
const baseCanvas = document.createElement('canvas')
const baseContext = baseCanvas.getContext('2d')
baseCanvas.width = img.width
baseCanvas.height = img.height
baseContext.drawImage(img, 0, 0, img.width, img.height)
//下载图片
baseCanvas.toBlob(function(blob) {
aveAs(blob, 'screen.png')
})
}
})
}
复杂进阶版:(多层瓦片图层与窗格叠加)
需要使用canvas画布,将每层瓦片图层imagedata取出来然后放在画布上一层一层叠加混合,最终画布成一个图片,难点转化像素
//截图leaflet地图
saveMap() {
const node = this.$refs.map.$el
domtoimage.toPng(node)
.then(dataUrl => {
this.mapHelp.toScreenImage(dataUrl)
})
},
mapHelp是我们封装的创建地图的类,类里方法toScreenImage如下:
toScreenImage(dataUrl) {
const canvas = this.airPortCollection.PixiMap.toScreenCanvas()
const context = canvas.getContext('2d')
const airdata = context.getImageData(0, 0, canvas.width, canvas.height)
const canvas_draw = this.pixiLayer.toScreenCanvas()
const context_draw = canvas_draw.getContext('2d')
const draw_data = context_draw.getImageData(
0,
0,
canvas_draw.width,
canvas_draw.height
)
var img = new Image()
img.src = dataUrl
img.onload = () => {
const baseContext = this.baseCanvas.getContext('2d')
this.baseCanvas.width = img.width
this.baseCanvas.height = img.height
baseContext.drawImage(img, 0, 0, img.width, img.height)
const baseImage = baseContext.getImageData(
0,
0,
canvas.width,
canvas.height
)
const imageData = blendImage(baseImage, [airdata.data, draw_data.data])
this.baseCanvas.width = canvas.width
this.baseCanvas.height = canvas.height
baseContext.putImageData(imageData, 0, 0)
this.baseCanvas.toBlob(function(blob) {
saveAs(blob, 'screen.png')
})
}
}
这里我们又封装了canvas类方法blendImage(混合图片)与traverse(将原始像素转化成我想要的像素rgba)
export function traverse(imageData, pass) {
const { width, height, data } = imageData
for (let i = 0; i < width * height * 4; i += 4) {
const [r, g, b, a] = pass({
r: data[i],
g: data[i + 1],
b: data[i + 2],
a: data[i + 3],
index: i,
width: width,
height: height,
x: (i / 4) % width,
y: Math.floor(i / 4 / width)
})
data.set([r, g, b, a].map(v => Math.round(v)), i)
}
return imageData
}
export function blendImage(baseData, datas) {
traverse(baseData, ({ r, g, b, a, index }) => {
for (let l = datas.length - 1; l >= 0; l--) {
// debugger
if (datas[l][index + 3] > 10) {
return [datas[l][index], datas[l][index + 1], datas[l][index + 2], datas[l][index + 3]]
}
}
return [r, g, b, a]
})
return baseData
}