A screenshot demo based on canvas in HTML

Time:2019-4-12

Written in the forefront

I remember seeing a share on everyone before, explaining the screenshot scheme based on js. I don’t remember in detail. I just remember that it seems interesting to use canvas? So this time I’m going to write my own thoughts to share with you. This is just a simple demo. If you have bugs, please mention issues. According to the usual Po code address.

Design sketch

A screenshot demo based on canvas in HTML

Overall thinking

  • Setting Start/End Shortcuts
  • Start by drawing DOM as canvas to cover the original DOM interface
  • Add a canvas mock-up area
  • Add a canvas browser interface to draw the corresponding mouse capture area (intercepted from the first canvas)
  • Save the intercepted image

1. Setting Start/End Shortcuts

Because of the conflicts that shortcut keys may cause, it is hoped that the number of shortcut keys can not be limited to start shortcut keys, so the first parameter is passed in the form of an array.

function screenShot(quickStartKey, EndKey) {
  // Compatibility considerations do not use... Extended strings
  var keyLength = quickStartKey.length
  var isKeyTrigger = {}
  var cantStartShot = false
  ...
  QuckStartKey. forEach (function (item) {// traversal parameter array
    IsKey Trigger [item] = false // All keys in the default array are not triggered
  })
  $('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 isKey Trigger [item]==== false /// See if there are any shortcuts that need to be triggered
      })
      If (notTrigger. length == 0) {// No shortcut keys need to be triggered to start the screenshot
        cantStartShot = true
        beginShot(cantStartShot)
      }
    }
  })

2. Draw DOM as canvas to cover the original DOM interface

If we adopt the native method, we can refer to the introduction of drawing DOM in canvas under MDN. The trickiest part is that you need to create an SVG image that contains XML, and the element involved is <foreignObject>. How to calculate the DOM displayed by the current browser and extract it is actually the most cumbersome. Well, in fact, the author does not have a good idea to implement a= manually. = So this html2 canvas library was chosen to do this. The general invocation method is as follows:

function beginShot(cantStartShot) {
    if(cantStartShot) {
        html2canvas(document.body, {
            onrendered: function(canvas) {
                // Get canvas images consistent with the interface
            }
        })
    }
}

3. Add a canvas mock-up area

The implementation of this place was originally intended to use the native canvas API, but it involves a problem that when the mouse is pressed and dragged, canvas will draw in real time, which will lead to a concept similar to PS layer. Every time MouseMove is drawn a current screenshot box, but the next time the MouseMove is triggered, the last screenshot box is deleted. In order to simulate the real-time rendering process. But the author did not find a way to use the canvas native API, if any, must tell me how to mark the drawings. In this paper, the author uses a Jq-based canvas library called Jcanvas, which gives the concept of layer, that is, only one picture can be drawn on a layer, and the name of the layer can be tagged. This meets the author’s needs and achieves the following:

$('#' + canvasId).mousedown(function(e) {
    $(""+canvasId). removeLayer (layerName)/// Delete the previous layer
    layerName += 1
    StartX = that. _calculateXY(e). x// Calculate mouse position
    startY = that._calculateXY(e).y
    isShot = true
    $("#"+canvasId).addLayer({
        Type:'rectangle', //rectangle
        ...
        Name: layerName, // Layer Name
        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 ();// Drawing
    }
    })

4. Add a canvas to draw the browser interface corresponding to the mouse screenshot area


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");

The image is intercepted by drawImage, and then converted to Base64 encoding by toDataURL method.

5. Save the intercepted image

function downloadFile(el, fileName, href){
      el.attr({
        'download':fileName,
        'href': href
      })
  }
  ...
downloadFile($('.ok'), 'screenShot' + Math.random().toString().split('.')[1] || Math.random()  + '.png', dataURL)
// Input key object, image save random name, Base64 encoded image

The download attribute of tag a is used, which can be downloaded directly after the user clicks.

deploy

Dependency


<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>

Configure shortcuts

ScreenShot ([16, 65], 27)// Start shortcut key set to shift + a; Exit key set to ESC

Last

The most disgusting part of the article (DOM writing canvas, canvas setting layer) uses two libraries to implement, and subsequent authors will continue to pay attention to how to use native APIs to achieve these operations, although I think I still write a little.

The above is the whole content of this article. I hope it will be helpful to everyone’s study, and I hope you will support developpaer more.