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

uniapp dynamic modification of element node style detailed explanation

Table of contents 1. Modify by binding the style ...

Docker Getting Started Installation Tutorial (Beginner Edition)

Doccer Introduction: Docker is a container-relate...

JavaScript implements password box verification information

This article example shares the specific code of ...

The iframe frame sets the white background to transparent in IE browser

Recently, I need to frequently use iframe to draw ...

VMware configuration VMnet8 network method steps

Table of contents 1. Introduction 2. Configuratio...

How to set an alias for a custom path in Vue

How to configure custom path aliases in Vue In ou...

Introduction to network drivers for Linux devices

Wired network: Ethernet Wireless network: 4G, wif...

Detailed explanation of the new background properties in CSS3

Previously, we knew several attributes of backgro...

JavaScript to achieve a simple message board case

Use Javascript to implement a message board examp...

Detailed explanation of two ways to dynamically change CSS styles in react

The first method: dynamically add a class to show...

How to migrate local mysql to server database

We can use the scp command of Linux (scp cannot b...

HTML 5 Preview

<br />Original: http://www.alistapart.com/ar...

jQuery to achieve the barrage effect case

This article shares the specific code of jQuery t...

How to install JDK 13 in Linux environment using compressed package

What is JDK? Well, if you don't know this que...

Detailed explanation of MySQL 8.0.18 commands

Open the folder C:\web\mysql-8.0.11 that you just...