title: React - how to copy an image to clipboard?
body: <p>im working on react web app and one of the feature needs to be implemented is to copy an image when clicked, so the user could paste it in: paint, word, etc...</p>
  
  <p>i tried several approaches, first was to follow the instructions detailed in this post: <a href="https://stackoverflow.com/a/40547470/9608006">https://stackoverflow.com/a/40547470/9608006</a></p>
  
  <p>this is what i came up with (the containerId refers to a div element which contains an image element as its first child): </p>
  
  <pre><code>copyImg = (containerId) =&gt; {
  const imgContainerElement = document.getElementById(containerId);
  this.selectText(imgContainerElement.children[0]);
  document.execCommand('copy');
  window.getSelection().removeAllRanges();
  alert('image copied!');
  }
  
  selectText = (element) =&gt; {
      var doc = document;
      if (doc.body.createTextRange) {
        var range = document.body.createTextRange();
        range.moveToElementText(element);
        range.select();
      } else if (window.getSelection) {
        var selection = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(element);
        selection.removeAllRanges();
        selection.addRange(range);
      }
    }
  </code></pre>
  
  <p>didn't work.
  I tried implement the solution marked with a 2 stars here: <a href="https://www.tek-tips.com/viewthread.cfm?qid=833917" rel="nofollow noreferrer">https://www.tek-tips.com/viewthread.cfm?qid=833917</a></p>
  
  <pre><code>  function copyImg(imgId){
    var r = document.body.createControlRange();
    r.add(document.getElementById(imgId));
    r.select();
    r.execCommand("COPY");
  }
  </code></pre>
  
  <p>but the createControlRange() is undefined.</p>
  
  <p>i tried using the navigator.clipboard api but it only works with png, and the app works with jpg.</p>
  
  <p>i looked for an npm library that can accomplish this, but all i found was for text-copying.
  npms like: react-copy-to-clipboard</p>
  
  <p>any help would be appreciated.</p>
  
  <p><strong>Edit 1:</strong> </p>
  
  <p>following dw_<a href="https://stackoverflow.com/a/59183698/9608006">https://stackoverflow.com/a/59183698/9608006</a> instructions this is what i came up with: 
  (note: i had to npm install babel-polyfill and import it in App.js, in order to make the async function to work and pass this error: regeneratorRuntime is not defined)</p>
  
  <pre><code>    copyImg = async (imgElementId) =&gt; {
      const imgElement = document.getElementById(imgElementId);
      const src = imgElement.src;
      const img = await fetch(src);
      const imgBlob = await img.blob();
      if (src.endsWith(".jpg") || src.endsWith(".jpeg")) {
        copyService.convertToPng(imgBlob);
      } else if (src.endsWith(".png")) {
        copyService.copyToClipboard(imgBlob);
      } else {
        console.error("Format unsupported");
      }
   }
  
  convertToPng = (imgBlob) =&gt; {
      const imageUrl = window.URL.createObjectURL(imgBlob);
      const canvas = document.createElement("canvas");
      const ctx = canvas.getContext("2d");
      const imageEl = createImage({ src: imageUrl });
      imageEl.onload = (e) =&gt; {
          canvas.width = e.target.width;
          canvas.height = e.target.height;
          ctx.drawImage(e.target, 0, 0, e.target.width, e.target.height);
          canvas.toBlob(copyToClipboard, "image/png", 1);
      };
  }
  
  createImage = (options) =&gt; {
      options = options || {};
      const img = (Image) ? new Image() : document.createElement("img");
      if (options.src) {
          img.src = options.src;
      }
      return img;
    }
  
  copyToClipboard = (pngBlob) =&gt; {
      try {
          navigator.clipboard.write([
              new ClipboardItem({
                  [pngBlob.type]: pngBlob
              })
          ]);
          console.log("Image copied");
      } catch (error) {
          console.error(error);
      }
  }
  </code></pre>
  
  <p>the code reaches to the Image copied message, but still when paste it on word it does not shown. anther thing is that i get </p>
  
  <blockquote>
    <p>console error: Uncaught (in promise) DOMException</p>
  </blockquote>