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

Detailed examples of replace and replace into in MySQL into_Mysql

MySQL replace and replace into are both frequentl...

iframe src assignment problem (server side)

I encountered this problem today. I reassigned the...

JavaScript Timer Details

Table of contents 1. Brief Introduction 2. setInt...

How to ensure that every page of WeChat Mini Program is logged in

Table of contents status quo Solution Further sol...

Native JS to implement sharing sidebar

This article shares a sharing sidebar implemented...

Detailed steps for developing WeChat mini-programs using Typescript

We don't need to elaborate too much on the ad...

Explanation of Truncate Table usage

TRUNCATE TABLE Deletes all rows in a table withou...

Example of horizontal arrangement of li tags in HTMl

Most navigation bars are arranged horizontally as...

Classification of web page color properties

Classification of color properties Any color can ...

Measured image HTTP request

Please open the test page in a mainstream browser...

Summary of MySQL lock knowledge points

The concept of lock ①. Lock, in real life, is a t...