1. Principle introduction

The script traverses the DOM of the page it loads. It collects information about all the elements there, and then uses that information to build a representation of the page. In other words, it doesn’t actually take a screen shot of the page, but builds its representation based on the properties it reads from the DOM.

As a result, it can only correctly render properties that it understands, which means that there are many CSS properties that don’t work. For a complete list of supported CSS properties, see the supported features page.

2. Plan

This library can convert HTML to canvas, and then convert canvas to image through canvasAPI. Finally, it can also download image through A tag

HTML -> Canvas -> image -> a[download]

  1. Html2canvas. Js: Convert HTMLDOM to canvas element. Github Portal
  2. CanvasAPI: toDataUrl() converts canvas to Base64 format
  3. Create a[Download] tag to trigger a click event for the download

3. Specific implementation code of the scheme

// Click generate image
generateImage() {
  if(this.state.productData.length>=100) {this.over100=true;
    this.isOver100Refresh=true;
    over100_list=this.state.productData
    this.state.productData=over100_list.slice(0.100)
    return
  }
  this.notMyTitle = false;
  this.notMyFooter = false;
  this.isLoadingBottom = false;
  document.querySelector('#area').scrollTop = 0;
  document.querySelector('.prodListH5').scrollLeft = 0;
  this.$refs.prodListH5Title.classList.remove('xiDing'); // Generate image error processing
  document.getElementById('area').style.height = 'auto';
  var rect = document.getElementById('appArea').getBoundingClientRect(); // Key code
  let height =
    rect.height +
    (158 * ((this.state.trList.width - 24) / 321) + 80 > 300 ? 158 * ((this.state.trList.width - 24) / 321) + 80 : 300); // Add the height of the image at the bottom (40 is the margin value) to avoid incomplete capture
  let width = rect.width;
  let userAgent = navigator.userAgent;
  // iPhone
  if (userAgent.includes('iPhone') || userAgent.includes('iPad')) {
    var scale = 3000000 / height / width > 2 ? 2 : 1;
  } else {
    // Get Google Chrome
    var scale = 14000 / height > 2 ? 2 : 1;
  }
  html2canvas(document.getElementById('appArea'), {
    // scrollY: 2 * rect.top, // key code
    scale, // Image too long processing
    scrollY: rect.top,
    height,
    width: rect.width,
  }).then((canvas) = > {
    canvas.toBlob((blob) = > {
      // this.imgUrl = URL.createObjectURL(blob)
      // var aImg = document.createElement("a");
      this.imgUrl = canvas.toDataURL('image/jpeg');
      var img = document.createElement('img');
      img.setAttribute('src'.this.imgUrl);
      img.className = 'imgItem';
      img.style.width = '100vw';
      img.style.height = 'auto';
      document.querySelector('.canvasImg').appendChild(img);
      document.querySelector('.imgBox').onclick = () = > {
        document.getElementById('area').style.height = '88vh';
        document.querySelector('.canvasImg').removeChild(img);
        document.querySelector('.imgBox').style.display = 'none';
        document.querySelector('.saveBtn').style.display = 'block';
        this.notMyTitle = true;
        this.notMyFooter = true;
        this.isLoadingBottom = true;
      };
      document.querySelector('.imgBox').style.display = 'block';
      document.querySelector('.saveBtn').style.display = 'none';
    }, 'image/png');
  });
},
Copy the code

4. Pothole avoidance Guide

(1) The picture is blurred

During the development of the project, there is a scrolling effect, and the captured picture is not only the width and height of the visual window. When the data is too much or the picture is too long, the picture will be blurred, which can be solved by setting the Scale configuration item

html2canvas(document.getElementById('appArea'), {
    // scrollY: 2 * rect.top, // key code
    scale, // Image too long processing
    scrollY: rect.top,
    height,
    width: rect.width,
  }).then((canvas) = >{...// The canvas has been drawn and the base64 image has been transferred to the canvas})
Copy the code

As for scale, the scale used for rendering. Default is browser device pixel ratio

/** * Get the pixel ratio according to window.devicepixelRatio */ 
function DPR() { 
    if (window.devicePixelRatio && window.devicePixelRatio > 1) { 
        return window.devicePixelRatio; 
        } 
    return 1; 
    }

Copy the code

(2) Text overlap occurs on some ios terminals

When text is automatically wrapped on a page and text is set to text-align:center, the height of the text will not change, but the text will overlap on one line. The rough solution is to set text-align:left to solve this problem.

By the way, previous attempts to render using V-HTML, manually adding line breaks, and keeping text-align:center were unsuccessful

The problem effect is shown in the figure below:

(3) The left and right areas of the screenshot are blank

Problems occur: when the page scrolls down or to the right of a certain distance, there will be incomplete interception and blank situation solution: 1. Before htmlDOM is converted to canvas, scroll the page to scrollTop when scrollLeft is 0

(4) The newly added business card at the bottom of the picture is not shown, with height (occupying the position) but blank

The reason for this problem: Canvas elements reach the browser’s Canvas size limit, and window limits vary by browser, operating system, and system hardware. The specific value

5. One day

(1)parseInt Notes

When using parseInt, try to specify a radix reason

/** * converts the passed value to an integer */ 
function parseValue(value) { 
    return parseInt(value, 10);
    };
Copy the code

Grammar:

parseInt(string, radix);
Copy the code

parameter

  • string

    The value to be parsed. If the argument is not a string, it is converted to a string (using the ToString abstraction operation). Whitespace at the beginning of the string will be ignored.

  • Radix optional

    The number from 2 to 36 represents the cardinality of the string. For example, if 16 is specified, the parsed value is a hexadecimal number. Note that 10 is not the default!

The return value

An integer resolved from a given string.

Or NaN, when

  • radixLess than2Or greater than36Or,
  • The first non-space character cannot be converted to a number.
ParseInt ('123', 5) // Treats '123' as a base 5 number and returns the decimal number 38 => 1*5^2 + 2*5^1 + 3*5^0 = 38Copy the code