A screenshot demo based on canvas in html

A screenshot demo based on canvas in html

Written at the beginning

I remember seeing a sharing on Renren before, which explained a screenshot solution based on JS. I don’t remember the details, but I just remember that it was quite interesting and seemed to use canvas? So this time I plan to write one myself to share with you the author’s ideas. This is just a simple demo. Please file an issue if you find any bugs. Follow the convention to post the code address.

Rendering

Overall idea

  • Set start/end shortcut keys
  • After the start, draw the DOM into canvas to cover the original DOM interface
  • Add a canvas to simulate the mouse screenshot area
  • Add a canvas to draw the browser interface corresponding to the mouse screenshot area (captured from the first canvas)
  • Save the captured image

1. Set start/end shortcut keys

Since shortcut keys may cause conflicts, we hope that there is no limit on the number of shortcut keys at the beginning, so we use an array to pass them in the first parameter.

function screenShot(quickStartKey, EndKey) {
  //Do not use...Extended string var keyLength = quickStartKey.length
  var isKeyTrigger = {}
  var cantStartShot = false
  ...
  quickStartKey.forEach(function(item) { //Traverse the parameter array isKeyTrigger[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 isKeyTrigger[item] === false // Check if there is any shortcut key that needs to be triggered})
      if(notTrigger.length === 0) { //No shortcut key needs to be triggered to start the screenshot cantStartShot = true
        beginShot(cantStartShot)
      }
    }
  })

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

If you use the native method, you can refer to the introduction of drawing DOM in canvas under MDN. The tricky part is that you need to create an SVG image containing the XML involved in the <foreignObject> element. How to calculate the DOM displayed by the current browser and extract it is actually the most cumbersome. Well, actually the author doesn't have any good ideas to manually implement a =. =, so I chose the html2canvas library to do this. The general calling method is as follows:

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

3. Add a canvas to simulate the mouse screenshot area

The implementation of this place was originally intended to use the native canvas API, but it involves a problem that after the mouse is pressed and dragging begins, the canvas needs to be drawn in real time. This requires a concept similar to PS layers. Every time the mouse moves, a current screenshot frame is drawn, but the next time the mouse moves, the previous screenshot frame is deleted. This simulates the real-time drawing process. Unfortunately, the author has not found a way to use the native API of canvas. If there is, please tell me how to mark the drawn image. Here the author uses a Jq-based canvas library called Jcanvas, which gives the concept of layers, that is, only one picture can be drawn on a layer, and the layer can be labeled with a name. This meets the author's needs and is implemented as follows:

$('#' + 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(); //Draw}
    })

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 captured by drawImage, and then the toDataURL method is used to convert the image into base64 encoding

5. Save the captured image

function downloadFile(el, fileName, href){
      el.attr({
        'download':fileName,
        'href': href
      })
  }
  ...
downloadFile($('.ok'), 'screenShot' + Math.random().toString().split('.')[1] || Math.random() + '.png', dataURL)
// Pass in the button object, random name for saving the image, and base64-encoded image

The download attribute of the a tag is used, and the download can be carried out directly when the user clicks it.

deploy

Dependencies

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

screenShot([16, 65], 27) // Start shortcut key is shift+a; exit key is ESC

at last

The most disgusting parts of the article (DOM writing to canvas, canvas setting layers) are implemented using two libraries respectively. In the future, the author will continue to focus on how to use native APIs to implement these operations, although I personally think that my writing is still a bit... .

The above is the full content of this article. I hope it will be helpful for everyone’s study. I also hope that everyone will support 123WORDPRESS.COM.

<<:  Eclipse configures Tomcat and Tomcat has invalid port solution

>>:  17 404 Pages You'll Want to Experience

Recommend

Vue3 implements Message component example

Table of contents Component Design Defining the f...

Use auto.js to realize the automatic daily check-in function

Use auto.js to automate daily check-in Due to the...

Native JS realizes uniform motion of various sports

This article shares with you a uniform motion imp...

Detailed explanation of various loop speed tests in JS that you don’t know

Table of contents Preface 1. for loop 2. while lo...

Detailed explanation of data types and schema optimization in MySQL

I'm currently learning about MySQL optimizati...

Optimal web page width and its compatible implementation method

1. When designing a web page, determining the widt...

How to use the Linux md5sum command

01. Command Overview md5sum - Calculate and verif...

Basic usage of find_in_set function in mysql

Preface This is a new function I came across rece...

The difference between float and position attributes in CSS layout

CSS Layout - position Property The position attri...

Application and implementation of data cache mechanism for small programs

Mini Program Data Cache Related Knowledge Data ca...

Example code for implementing simple ListViews effect in html

HTML to achieve simple ListViews effect Result: c...

How to implement Mysql scheduled task backup data under Linux

Preface Backup is the basis of disaster recovery....

Windows Server 2008 R2 Multi-User Remote Desktop Connection Licensing

At work, we often need remote servers and often e...