html 根据 canvas 完成的1个截图小demo

写在最前

记得之前在人人上看到1个共享,解读根据js的截图计划方案,详尽的不记得了,只记得还挺成心思的貌似用了canvas?因此这次准备自身写1个共享给大伙儿作者的思路。这只是1个很简单的小demo如有bug请提issues。依照国际惯例po编码详细地址。

实际效果图

总体思路

  • 设定刚开始/完毕便捷键
  • 刚开始后将DOM绘图成canvas来遮盖初始DOM页面
  • 加上1张canvas仿真模拟电脑鼠标截图地区
  • 加上1张canvas用来绘图电脑鼠标截图地区对应的访问器页面(从第1张canvas中截取)
  • 储存截取的图象

1.设定刚开始/完毕便捷键

因为便捷键将会致使的矛盾故期待刚开始便捷键能够不限制便捷键数量,因此在第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的详细介绍。里边最繁杂的地区是你必须建立1个包括XML的SVG图象涉及到到的元素为<foreignObject>。怎样能测算出当今访问器显示信息的DOM而且将其提取下来实际上是最繁琐的。好的实际上作者也沒有好的思路手动式完成1个=。=,因此挑选了这个html2canvas库来进行这件事。大概启用方法以下:

function beginShot(cantStartShot) {
    if(cantStartShot) {
        html2canvas(document.body, {
            onrendered: function(canvas) {
                //获得与页面1致的canvas图象
            }
        })
    }
}

3.加上1张canvas仿真模拟电脑鼠标截图地区

这个地区的完成原本准备应用原生态canvasAPI,可是里边涉及到到1个难题便是在电脑鼠标按下刚开始拖拽后,canvas要即时绘图,这里边就要引出1个相近于PS涂层的定义,每当mousemove的情况下都画出1个当今的截图框,可是当下1次开启mousemove的情况下就删除上1个截图框。以此来仿真模拟即时的绘图全过程。无可奈何作者沒有寻找应用canvas原生态API的方式,假如有的话1定告知我怎样对画出的图做出标识。在这里作者应用了1个根据Jq的canvas的库叫做Jcanvas,里边得出了涂层的定义,即在1个涂层上只能画1张图,另外能够给涂层标识名字。这就考虑了作者的要求,完成以下:

$('#' + canvasId).mousedown(function(e) {
    $("#"+canvasId).removeLayer(layerName) //删掉上1涂层
    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.加上1张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方式将图象变换以便base64编号

5.储存截取的图象

function downloadFile(el, fileName, href){
      el.attr({
        'download':fileName,
        'href': href
      })
  }
  ...
downloadFile($('.ok'), 'screenShot' + Math.random().toString().split('.')[1] || Math.random()  + '.png', dataURL)
// 传入功能键目标、图象储存任意名、base64编号的图象

在其中用到了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来完成这些实际操作,尽管本人觉得自身写還是有点。。

以上便是本文的所有內容,期待对大伙儿的学习培训有一定的协助,也期待大伙儿多多适用脚本制作之家。