Search code examples
reactjsamazon-web-servicesamazon-s3html2canvas

How can I solve the html2canvas image cross origin issue?


I'm attempting to convert a DOM element to a PNG image. Everything works OK except for the cross origin images, which appear as empty spaces in the image. I tried adding extra props of useCors: true, but that doesn't work.

Here's the code:

 const exportAsPicture = () => {
    var html = document.getElementsByTagName("HTML")[0];
    var body = document.getElementsByTagName("BODY")[0];
    var htmlWidth = html.clientWidth;
    var bodyWidth = body.clientWidth;
    var data = document.getElementById(`${idea.slug}`);
    var newWidth = data.scrollWidth - data.clientWidth;
    if (newWidth > data.clientWidth) {
      htmlWidth += newWidth;
      bodyWidth += newWidth;
    }
    html.style.width = htmlWidth + "px";
    body.style.width = bodyWidth + "px";
    data.style.boxShadow = "none";
    console.log(data);
    html2canvas(data, {
      logging: true,
      letterRendering: 1,
      proxy: "https://notepd.s3.amazonaws.com/",
      useCORS: true,
    })
      .then((canvas) => {
        var image = canvas.toDataURL("image/png", 0.1);
        data.style.boxShadow = "0px 4px 4px rgba(0, 0, 0, 0.08)";

        return image;
      })
      .then((image) => {
        saveAs(image, `NotePD | ${idea.title}.png`);
        html.style.width = null;
        body.style.width = null;
      });
  };

  const saveAs = (blob, fileName) => {
    var elem = window.document.createElement("a");
    elem.href = blob;
    elem.download = fileName;
    elem.style = "display:none;";
    (document.body || document.documentElement).appendChild(elem);
    if (typeof elem.click === "function") {
      elem.click();
    } else {
      elem.target = "_blank";
      elem.dispatchEvent(
        new MouseEvent("click", {
          view: window,
          bubbles: true,
          cancelable: true,
        })
      );
    }
    URL.revokeObjectURL(elem.href);
    elem.remove();
  };

The picture is coming from the s3Bucket the same origin images renders well


Solution

  • Just add crossOrigin="anonymous" to your image it will solve the issue