admin 管理员组

文章数量: 1184232

实现截图(红框中即是将要截取的内容)

下载到本地的截图

功能需求

近日。 项目中有一需求:在 地图中进行框选截图,同时把地图中的所有标记和图形一同截图,并下载到本地。

搜索资源

在网上搜索了一下,找到一个截图的js库 。网上的大部分例子都是基于html2canvas来完成的。找一圈并未找到现成的轮子,那就自己造一个吧。

功能拆分

框选:绘制矩形 ------» 截图:html2canvas -----»下载:生成a标签 -----» 模拟点击:下载完成。大致应该是上面三个步骤。

  1. 框选: 绘制矩形 。文中使用的绘制插件是: 。
    代码如下:
// 矩形实例let rectangle =newL.Draw.Rectangle(this.map,{
          shapeOptions:{
            stroke:true,
            color:'red',
            weight:2,
            opacity:0.9,
            fill:true,
            fillColor:null,/*same as color by default*/
            fillOpacity:0.1,
            clickable:true}});
        rectangle.enable();//绘制矩形this.map.on(L.Draw.Event.CREATED,(e)=>{if(this.currentLayerType == type && e.layerType =='rectangle'){this.featureGroup.addLayer(e.layer);if(!e.layer.flag){this.$confirm('是否下载本次截图','提示',{
                confirmButtonText:'下载',
                cancelButtonText:'取消',
                type:'warning',
                showClose:false,
                center:true}).then(()=>{let latlngs = e.layer._latlngs[0]// 获取矩形的 经纬度 list// console.log(latlngs)this.featureGroup.removeLayer(e.layer);// 移除框选的矩形this.captureScreenEnd(latlngs);// 开始截图this.$message({
                  type:'success',
                  message:'下载成功!',
                  offset:100});}).catch(()=>{this.featureGroup.removeLayer(e.layer);});}
            e.layer.flag =true}});this.map.on(L.Draw.Event.DRAWSTOP,(e)=>{
          console.log('框选截图结束====')
          rectangle.disable()});
  1. 截图 : 功能核心代码
    代码如下:
let bounds =this.map.getBounds(),
            zero =[bounds._northEast.lat,bounds._southWest.lng],// 计算当前 视窗内的 原点经纬度 ==> 对应的屏幕坐标 (地图位移及缩放时计算 startPoint的偏移量)必须!!!
            zeroPoint = map.latLngToLayerPoint(zero)let startPoint = map.latLngToLayerPoint(points[1]),// latlng 转 屏幕坐标 计算 起点及宽高
            endPoint =  map.latLngToLayerPoint(points[3]),
            width = Math.abs(startPoint.x - endPoint.x),
            height = Math.abs(startPoint.y - endPoint.y);html2canvas(document.getElementById('map'),{
          useCORS:true,// 底图跨域 必须!!// allowTaint:false}).then((canvas)=>{this.downloadIamge(canvas,(startPoint.x - zeroPoint.x),(startPoint.y - zeroPoint.y),width,height)this.resetToolbar()});
  1. 下载: 截图下载
    代码如下:
// 创建一个用于截取的canvasvar clipCanvas = document.createElement('canvas')
        clipCanvas.width = capture_width
        clipCanvas.height = capture_height
        // 截取图片
        clipCanvas.getContext('2d').drawImage(canvas, capture_x, capture_y, capture_width, capture_height,0,0, capture_width, capture_height)var clipImgBase64 = clipCanvas.toDataURL()// 生成图片url// 下载图片let link = document.createElement("a");
        link.href = clipImgBase64;//下载链接
        link.setAttribute("download",newDate().toLocaleString()+"_截图.png");
        link.style.display ="none";//a标签隐藏
        document.body.appendChild(link);
        link.click();// 点击下载
        document.body.removeChild(link);// 移除a标签
进阶功能

此功能是基于地图矩形绘制来实现的。如果要实际网页版的框选截图如何实现?原理都是一样的,只是第一步的框选用canvas来进行绘制就可以了。本文使用的是 ,核心代码如下:

import html2canvas from'html2canvas'exportconst screenShot ={/**
     *  画矩形
     * @param canvasId canvasId
     * @param penColor 画笔颜色
     * @param strokeWidth 线宽
     */
    cancelFlag:false,// 是否可以进行截图操作
    defaultStrokeWidth:1,// 默认画矩形选取框的线宽
    defaultLineColor:'blue',
    init:function(canvasId, targetId){var that =this;// 注册 esc 监控取消事件$("#"+ canvasId).show()
        document.body.style.cursor ='crosshair';
        that.cancelFlag =true},
    drawRect:function(canvasId, targetId, penColor, strokeWidth, callback){var that =this;
        that.init(canvasId, targetId);
        that.penColor = penColor || that.defaultLineColor;
        that.penWidth = strokeWidth || that.defaultStrokeWidth;var canvas = document.getElementById(canvasId);//canvas 的矩形框var canvasRect = canvas.getBoundingClientRect();//canvas 矩形框的左上角坐标var canvasLeft = canvasRect.left;var canvasTop = canvasRect.top;// 要画的矩形的起点 xyvar x =0;var y =0;
        document.addEventListener('keydown',function(e){//此处填写你的业务逻辑即可if(e.keyCode ==27){
                that.cancel(canvasId, callback);
                x = e.clientX - canvasLeft;
                y = e.clientY - canvasTop;}})//鼠标点击按下事件,画图准备
        canvas.onmousedown=function(e){if(!that.cancelFlag){return}//设置画笔颜色和宽度var color = that.penColor;var penWidth = that.penWidth;// 确定起点
            x = e.clientX - canvasLeft;
            y = e.clientY - canvasTop;
            console.log('down=====>', x, y)// 添加layer$("#"+ canvasId).addLayer({
                type:'rectangle',
                strokeStyle: color,
                strokeWidth: penWidth,
                name:'areaLayer',
                fromCenter:false,
                x: x, y: y,
                width:1,
                height:1});// 绘制$("#"+ canvasId).drawLayers();$("#"+ canvasId).saveCanvas();//鼠标移动事件,画图
            canvas.onmousemove=function(e){// 要画的矩形的宽高var width = e.clientX - canvasLeft - x;var height = e.clientY - canvasTop - y;
                console.log('move=====>', width, height)// 清除之前画的$("#"+ canvasId).removeLayer('areaLayer');$("#"+ canvasId).addLayer({
                    type:'rectangle',
                    strokeStyle: color,
                    strokeWidth: penWidth,
                    name:'areaLayer',
                    fromCenter:false,
                    x: x, y: y,
                    width: width,
                    height: height,});$("#"+ canvasId).drawLayers();}};//鼠标抬起
        canvas.onmouseup=function(e){if(!that.cancelFlag){return}var color = that.penColor;var penWidth = that.penWidth;
            canvas.onmousemove =null;
            console.log('up=====>', x, y)var width = e.clientX - canvasLeft - x;var height = e.clientY - canvasTop - y;$("#"+ canvasId).removeLayer('areaLayer');$("#"+ canvasId).addLayer({
                type:'rectangle',
                strokeStyle: color,
                strokeWidth: penWidth,
                name:'areaLayer',
                fromCenter:false,
                x: x, y: y,
                width: width,
                height: height
            });$("#"+ canvasId).drawLayers();// 绘制矩形$("#"+ canvasId).saveCanvas();// 保存矩形// 把body转成canvashtml2canvas(document.getElementById(targetId),{
                scale:1,// allowTaint: true,
                useCORS:true//跨域使用}).then(canvas =>{var capture_x, capture_y
                if(width >0){//从左往右画
                    capture_x = x + that.penWidth
                }else{//从右往左画
                    capture_x = x + width + that.penWidth
                }if(height >0){//从上往下画
                    capture_y = y + that.penWidth
                }else{//从下往上画
                    capture_y = y + height + that.penWidth
                }
                that.printClip(canvas, capture_x, capture_y, Math.abs(width), Math.abs(height))});
            that.cancel(canvasId, callback)
            callback &&callback();}},// 结束 取消截图
    cancel:function(canvasId, callback){
        document.body.style.cursor ='auto'$("#"+ canvasId).removeLayer('areaLayer');$("#"+ canvasId).clearCanvas()$("#"+ canvasId).hide()this.cancelFlag =false
        callback &&callback()},/**
     * 截取区域转为图片
     * @param canvas 截取的canvas
     * @param capture_x 截取的起点x
     * @param capture_y 截取的起点y
     * @param capture_width 截取的起点宽
     * @param capture_height 截取的起点高
     */
    printClip:function(canvas, capture_x, capture_y, capture_width, capture_height){// 创建一个用于截取的canvasvar clipCanvas = document.createElement('canvas')
        clipCanvas.width = capture_width
        clipCanvas.height = capture_height
        // 截取
        clipCanvas.getContext('2d').drawImage(canvas, capture_x, capture_y, capture_width, capture_height,0,0, capture_width, capture_height)var clipImgBase64 = clipCanvas.toDataURL()this.downloadIamge(clipImgBase64)// 下载图片},/**
     * 下载保存图片
     * @param imgUrl 图片地址
     */
    downloadIamge:function(imgUrl){let link = document.createElement("a");
        link.href = imgUrl;//下载链接
        link.setAttribute("download",newDate().toLocaleString()+"_截图.png");
        link.style.display ="none";//a标签隐藏
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link)}};
结束语

好了。框选截图的功能基本就写完了,希望本文对您在关于地图及cavnas有一个简单的了解。

感谢您的阅读,希望本文对您有所帮助。 —— chysxslt

本文标签: 编程 绘制矩形 截取的起