视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
html基于canvas实现截图的介绍
2020-11-27 15:05:02 责编:小采
文档
 本篇文章主要介绍了html 基于 canvas 实现的一个截图小demo,具有一定的参考价值,有兴趣的可以了解一下

写在最前

记得以前在人人上看到一个分享,讲解基于js的截图方案,详细的不记得了,只记得还挺有意思的貌似用了canvas?所以这次打算自己写一个分享给大家作者的思路。这只是一个很简陋的小demo如有bug请提issues。按照惯例po代码地址。

效果图

整体思路

  • 设置开始/结束快捷键

  • 开始后将DOM绘制成canvas来覆盖原始DOM界面

  • 添加一张canvas模拟鼠标截图区域

  • 添加一张canvas用来绘制鼠标截图区域对应的浏览器界面(从第一张canvas中截取)

  • 保存截取的图像

  • 1.设置开始/结束快捷键

    由于快捷键可能导致的冲突故希望开始快捷键可以不限定快捷键数量,所以在第一个参数中采用了数组的形式进行传递。

    function screenShot(quickStartKey, EndKey) {
     //兼容性考虑不使用...扩展字符串
     var keyLength = quickStartKey.length
     var isKeyTrigger = {}
     var cantStartShot = false
     ...
     quickStartKey.forEach(function(item) { //遍历参数数组
     isKeyTrigger[item] = false //默认数组中所有键都没有触发
     })
     $('html').on('keyup', function(e) {
     var keyCode = e.which
     if(keyCode === EndKey) {
     ...
     } else if(!cantStartShot) {
     isKeyTrigger[keyCode] = true
     var notTrigger = Object.keys(isKeyTrigger).filter(function(item) {
     return isKeyTrigger[item] === false //查看有没有需要触发的快捷键
     })
     if(notTrigger.length === 0) { //没有需要触发的快捷键即可以开始截图
     cantStartShot = true
     beginShot(cantStartShot)
     }
     }
     })

    2.将的DOM绘制成canvas来覆盖原始DOM界面

    如果采用原生的方法可以参照MDN下对于在canvas中绘制DOM的介绍。里面最棘手的地方是你需要创建一个包含XML的SVG图像涉及到的元素为<foreignObject>。如何能计算出当前浏览器显示的DOM并且将其提取出来其实是最繁琐的。好的其实作者也没有好的思路手动实现一个=。=,所以选择了这个html2canvas库来完成这件事。大致调用方式如下:

    function beginShot(cantStartShot) {
     if(cantStartShot) {
     html2canvas(document.body, {
     onrendered: function(canvas) {
     //得到与界面一致的canvas图像
     }
     })
     }
    }

    3.添加一张canvas模拟鼠标截图区域

    这个地方的实现本来打算使用原生canvasAPI,但是里面涉及到一个问题就是在鼠标按下开始拖拽后,canvas要实时绘制,这里面就要引出一个类似于PS图层的概念,每当mousemove的时候都画出一个当前的截图框,但是当下一次触发mousemove的时候就删掉上一个截图框。以此来模拟实时的绘制过程。无奈作者没有找到使用canvas原生API的方法,如果有的话一定告诉我如何对画出的图做出标记。在这里作者使用了一个基于Jq的canvas的库叫做Jcanvas,里面给出了图层的概念,即在一个图层上只能画一张图,同时可以给图层标记名称。这就满足了作者的需求,实现如下:

    $('#' + canvasId).mousedown(function(e) {
     $("#"+canvasId).removeLayer(layerName) //删除上一图层
     layerName += 1
     startX = that._calculateXY(e).x //计算鼠标位置
     startY = that._calculateXY(e).y
     isShot = true
     $("#"+canvasId).addLayer({
     type: 'rectangle', //矩形
     ...
     name:layerName, //图层名称
     x: startX,
     y: startY,
     width: 1,
     height: 1
     })
    }).mousemove(function(e) {
     if(isShot) {
     $("#"+canvasId).removeLayer(layerName)
     var moveX = that._calculateXY(e).x
     var moveY = that._calculateXY(e).y
     var width = moveX - startX
     var height = moveY - startY
     $("#"+canvasId).addLayer({
     type: 'rectangle',
     ...
     name:layerName,
     fromCenter: false,
     x: startX,
     y: startY,
     width: width,
     height: height
     })
     $("#"+canvasId).drawLayers(); //绘制
     }
     })

    4.添加一张canvas用来绘制鼠标截图区域对应的浏览器界面

    var canvasResult = document.getElementById('canvasResult')
     var ctx = canvasResult.getContext("2d");
     ctx.drawImage(copyDomCanvas, moveX - startX > 0 ? startX : moveX, moveY - startY > 0 ? startY : moveY, width, height, 0, 0, width, height )
     var dataURL = canvasResult.toDataURL("image/png");

    其中通过drawImage截取了图像,再使用toDataURL方法将图像转换为了base编码

    5.保存截取的图像

    function downloadFile(el, fileName, href){
     el.attr({
     'download':fileName,
     'href': href
     })
     }
     ...
    downloadFile($('.ok'), 'screenShot' + Math.random().toString().split('.')[1] || Math.random() + '.png', dataURL)
    // 传入按键对象、图像保存随机名、base编码的图像

    其中用到了a标签的download属性,当用户点击之后就可以直接进行下载。

    部署

    依赖项

    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
    <script src="https://cdn.bootcss.com/jcanvas/16.7.3/jcanvas.min.js"></script>
    <script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>

    配置快捷键

    screenShot([16, 65], 27) // 开始快捷键设置为shift+a;退出键为ESC

    最后

    文中最恶心的地方(DOM写入canvas、canvas设置图层)分别采用了两个库来进行实现,后续作者还会陆续关注如何使用原生API来实现这些操作,虽然个人认为自己写还是有点。

    下载本文
    显示全文
    专题