leaflet使用domtoimage插件与h5 canvas实现截图功能并下载

简介: leaflet使用domtoimage插件与h5 canvas实现截图功能并下载

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>元素
            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
}


相关文章
|
JSON 前端开发 定位技术
Leaflet开发:webgl方式加载point
Leaflet开发:webgl方式加载point
298 0
Leaflet开发:webgl方式加载point
|
JavaScript 定位技术
基于Leaflet.draw的gis图形标绘实战
本文将通过编码的方式讲解如何引入Leaflet.draw组件,并绘制点、线、面、圆对象,同时可以计算线的距离,面积,圆半径和点的经纬度等信息。通过本文可了解基本操作,可以基于leaflet扩展相关的绘制组件,为空间检索等
734 0
基于Leaflet.draw的gis图形标绘实战
|
算法 JavaScript 数据可视化
基于leaflet-velocity的二维动态风场展示
本文讲解了leaflet-velocity插件,并利用插件进行了模拟的动态风场、洋流等信息的综合展示,让读者掌握集成方式。
1211 0
基于leaflet-velocity的二维动态风场展示
|
JavaScript 前端开发 定位技术
Leaflet系列:加载GeoJSON数据
Leaflet如何加载GeoJSON数据
1146 0
|
JSON JavaScript 数据格式
Vue中 引入使用 vue-json-editor
Vue中 引入使用 vue-json-editor
1826 0
Vue中 引入使用 vue-json-editor
|
9月前
|
数据可视化 索引
数据可视化之antv/g6 元素之边(edge)
数据可视化之antv/g6 元素之边(edge)
1561 0
npm如何切换淘宝源镜像
npm如何切换淘宝源镜像
3894 0
|
SQL 安全 Java
Java阿里巴巴代码规范
Java阿里巴巴代码规范
21239 0
|
JavaScript
element-plus 按需引入将英文组件修改为中文
element-plus 按需引入将英文组件修改为中文
element-plus 按需引入将英文组件修改为中文
|
9月前
|
JavaScript
引入echarts时报错 “TypeError: Cannot read properties of undefined (reading ‘init‘)“的解决方案
引入echarts时报错 “TypeError: Cannot read properties of undefined (reading ‘init‘)“的解决方案
629 0
引入echarts时报错 “TypeError: Cannot read properties of undefined (reading ‘init‘)“的解决方案

热门文章

最新文章