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参考文档:
实现思路:
简单版:(单个图不叠加不使用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>元素 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 }