background

Generate a shared image, including the text and text returned by the back end. The image is a CDN resource. When I first tried to use HTML2Canvas, I used local images and generated screenshots without problem.

Code implementation

import html2canvas from 'html2canvas';
const shareContent = document.getElementById("capture"); // The content area to generate the screenshot
(window.html2canvas || html2canvas)(shareContent, {
  useCORS: true.
  scrollY: 0.scrollX: 0.height:shareContent.offsetHeight - 2,
}).then((canvas) = > {
  console.log("Generate the whole picture");
  setUrl(canvas.toDataURL("image/png".1))})Copy the code

The problem

However, when CDN resources are changed, the screenshot is blank and the picture cannot be displayed randomly on the ios device.

The solution

Since local images are used, this problem is not encountered, so when the front end obtains image CDN resources,

  1. Asynchronously convert resources to Base64
  2. Assign base64 to the IMG tag
  3. Finally, execute the code that generates the screenshot

The problem was solved after the test

Code implementation

  1. Multiple CDN images need to be loaded, so Promise is used to process multiple CDN images into Base64
// Pass in the CDN address
function convertUrlToBase64(url) {
    return new Promise((resolve) = > {
        let img = new Image();
        img.crossOrigin = 'Anonymous';
        img.src = url;
        img.onload = function () {
            let canvas = document.createElement('canvas');
            canvas.width = img.width;
            canvas.height = img.height;
            let ctx = canvas.getContext('2d');
            ctx.drawImage(img, 0.0, img.width, img.height);
            let ext = img.src.substring(img.src.lastIndexOf('. ') + 1).toLowerCase();
            let dataURL = canvas.toDataURL('image/' + ext);
            let base64 = {
                dataURL: dataURL,
                type: 'image/' + ext,
                ext: ext
            };
            resolve(base64)
        }
    })
}
Copy the code
  1. After loading multiple images asynchronously, base64 was assigned to the IMG tag, and finally the screenshot was generated
const bgImg = document.getElementsByClassName('photo') [0];
const avatarImg = document.getElementsByClassName('avatar') [0]
Promise.all([convertUrlToBase64(bgImg.src), convertUrlToBase64(avatarImg.src)])
    .then(([base641,base642]) = > {
        bgImg.src = base641.dataURL;
        avatarImg.src = base642.dataURL;
        (window.html2canvas || html2canvas)(shareContent, {
          useCORS: true.scrollY: 0.scrollX: 0.height:shareContent.offsetHeight - 2,
        }).then((canvas) = > {
          console.log("Generate the whole picture");
          setUrl(canvas.toDataURL("image/png".1)) Toast.hide(); })})Copy the code

conclusion

Html2canvas generates screenshots, and the problem of not showing CDN pictures has been solved perfectly. 🎉

In the process of using, I encountered that the whole text moved down when generating screenshots, which has not been solved yet. I can see issue github.com/niklasvh/ht…