Leaflet框选截图 网页框选截图 -- 类似QQ截图功能

  • 功能需求
  • 搜索资源
  • 功能拆分
  • 进阶功能
  • 结束语

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

下载到本地的截图

功能需求

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

搜索资源

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

功能拆分

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

  1. 框选:绘制矩形。文中使用的绘制插件是:Leaflet.draw。
    代码如下:
// 矩形实例let rectangle = new L.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_widthclipCanvas.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", new Date().toLocaleString() + "_截图.png");link.style.display = "none";//a标签隐藏document.body.appendChild(link);link.click(); // 点击下载document.body.removeChild(link); // 移除a标签
进阶功能

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


import html2canvas from 'html2canvas'export const 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_yif (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 = falsecallback && 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_widthclipCanvas.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", new Date().toLocaleString() + "_截图.png");link.style.display = "none";//a标签隐藏document.body.appendChild(link);link.click();document.body.removeChild(link)}
};
结束语

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

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

Leaflet框选截图 网页框选截图 -- 类似QQ截图功能相关推荐

  1. Ubuntu中类似QQ截图的截图工具并实现鼠标右键菜单截图

    文章目录 简介: 安装: 设置快捷键: 实现鼠标右键菜单截图: 简介: 在Windows中用惯了强大易用的QQ截图,会不习惯Ubuntu中的截图工具. 软件名为火焰截图,功能类似QQ截图,可以设置快捷 ...

  2. qq截图快捷键,小编教你qq截图快捷键怎么设置

    背景描述 在我们日常生活中经常会使用QQ对一些图片进行截图,并且QQ截图的快捷键默认都是为Ctrl+Atl+A,有时候快捷键会产生冲突,例如小编在截图谷歌浏览器时遇到截图冲突,但是这个默认的快捷键组合 ...

  3. QT做类似QQ截图功能(带图片编辑功能)

    这里采用的方法是按下截屏按钮截取整个桌面,然后通过鼠标的拖动选中截取的区域, 并把这个区域用截取的那张大图中相应的位置设置为QLabel背景, 实现了类似QQ的图片编辑功能,划线.矩形.画圆.文字编辑 ...

  4. 制作类似QQ截图软件

    最近在学习GDI,发现网上几篇文章在讲截图软件制作方法,学习了一点知识,在这里分享一下. 主要是调用WinAPI中的函数来完成主要功能.关键的函数有2个,一个是CreateDC,利用这个函数来创建一个 ...

  5. vue实现PS效果,鼠标拖拽指令、十字辅助线、鼠标选点、打印页面指定内容、生成随机id、颜色选择器、div上输入文字(类似QQ截图输入文字)、vue图片上传转base64...

    因为涵盖的小细节比较多,所以代码比较长,建议大家复制运行来进行对应功能查看,我在代码中添加了大量的注释,以供大家阅读代码 最终效果 部分细节 1.鼠标选点时可能会超出底图位置 2.图片的backgro ...

  6. QQ截图无法截取右键菜单等内容解决方案

    做教程截图步骤的时候,使用QQ截图很方便,但QQ截图对于鼠标右键显示的内容无法截取,这一点不是很方便,主要是QQ截图快捷键和系统冲突了,QQ截图快捷键默认为Ctrl+Alt+A,主要是Alt导致.我们 ...

  7. Qt实现仿QQ截图,带绘图,撤回功能!

    Qt实现仿QQ截图 想自己用Qt做个东西玩玩,偶然间看到小猪老师做的截图文章 做的很棒,但是看到最后没有发现绘图功能,然后百度了各种用qt制作的截图软件,大部分都不带绘图功能,于是我便打算在小猪老师代 ...

  8. Windows截图工具,QQ截图独立版,QQ截图独立运行版,不需要登录QQ,体积小巧,独立运行的高效截图工具,支持截图文字识别和截图搜索,支持截图涂鸦和标记

    QQ自带的截图功能真的很强大,而且非常方便,包含了多种实用的功能,可以在截图上进行标记,可以截图进行文字提取等.现在有人把这个功能从QQ上分离出来了,在没有网络不登录QQ的情况下也可以使用这个截图工具 ...

  9. 2020年7月win32 C\C++ API 写的仿QQ截图功能

    2020年7月win32 C\C++ API 写的仿QQ截图功能 近日,经常用到截图,但是没有QQ没有微信 的电脑上,截图非常不方便,起初打算网上随便找个类似的就算了,但是找了一下午,发现都是些很基础 ...

最新文章

  1. 使用Python实现真正意义上的随机数,谁能破解奖励1千万
  2. POJ3070矩阵快速幂简单题
  3. linux编译避免污染源码分离,如何避免linux上的系统标准C/C++库?
  4. 深度 | 带领国产数据库走向世界,POLARDB底层逻辑是什么?
  5. 字符串第一个出现的单个字符_如何在不编写单个应用程序的情况下找到我的第一个开发人员工作
  6. linux安装协议,在Linux中安装IPv6协议
  7. ppt图片文字嵌入_形状,文字填充图片教你做出好看的PPT
  8. php获取qq音乐的api类,利用QQ音乐api集成的php歌曲搜索
  9. 图片批量转换成jpg格式的方法!
  10. Android9.0 vendor分区整包升级
  11. 深入 Parcel架构与流程
  12. python语言折半查找_c# 折半查找法实现代码
  13. 2021-2022年小学期 程序设计开发实践 随堂笔记
  14. 8个酷炫的GitHub技巧
  15. web应用防火墙的部署方式
  16. 有财学院http://www.godgold.com/learn/title_asp/index.html
  17. SPSSModeler的下载与安装
  18. 自定义广告联盟接入解决方案,适用所有广告商接入。
  19. nacos server 安装报错 macOS 10.12.6
  20. Oracle 12c以下版本RAC与Redhat Linux的avahi-daemon服务的水火不容

热门文章

  1. 高德地图多边形覆盖物等间距缩小或者放大算法
  2. 腾讯云服务器增加网卡,腾讯云绑定和配置弹性网卡
  3. 遥感数据几何精校正的重要误区
  4. pda扫描枪屏幕_PDA扫描枪方案
  5. ExoPlayer实现4G网络下暂停缓存功能
  6. 安庆师范大学计算机与信息学院考研光荣榜,信息工程学院2016级考研考公光荣榜(十)...
  7. 2019蓝桥杯A组C++题目
  8. 【基线,内容区, 行高/行间距,行距, 行内框,行框的 区分说明】
  9. 神经网络算法的基本原理,人工神经网络算法步骤
  10. 昨天整天在刻碟,今天要继续学习才行了。。。