Copy SVG to clipboard as image

Viewed 1620

I am working on an application where I want to provide a copy button for svg to be copied as an image to clipboard which can be pasted at other places.

I tried using clipboard API but it has a lot of security restrictions, moreover it does not seem to work on http and works with png only.

I also tried the document.execCommand('copy') by creating a div with the image but it worked for me only in MS Word but not in slack or stack overflow (not sure why).

I want to replicate the behaviour of chrome/firefox's right click context-menu's Copy Image option via Javascript.

Is there some way this is possible? I am open to all ideas. Thanks!

2 Answers

Just some pointers, not an actual answer. I set up a local example using the info in the comments:

<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" style="border:2px solid green;" width="300" height="300"> 
</canvas>
      <script>
        function copyCanvas() {
          let canvas = document.getElementById('myCanvas');
          canvas.toBlob(function (blob) {
            let data = [new ClipboardItem({ [blob.type]: blob })];

            navigator.clipboard.write(data).then(function () {
              alert('Copied');
            }, function (err) {
              alert('Not copied');
            })
          });
        }
  
         let canvas = document.getElementById('myCanvas');
         let ctx = canvas.getContext('2d');
         var data = `<svg xmlns="http://www.w3.org/2000/svg" width="300"
         height="200">' +
            '<foreignObject width="100%" height="100%">' +
               '<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:50px">' +
                  'Simply Easy ' +
                  '<span style="color:blue;">' +
                  'Learning</span>' +
               '</div>' +
            '</foreignObject>' +
         '</svg>`;
         var DOMURL = window.URL || window.webkitURL || window;
         var img1 = new Image();
         var svg = new Blob([data], {type: 'image/svg+xml'});
         var url = DOMURL.createObjectURL(svg);
         img1.onload = function() {
            ctx.drawImage(img1, 25, 70);
            DOMURL.revokeObjectURL(url);
         }
         img1.src = url;
         setTimeout(copyCanvas, 3000);
      </script>
</body>
</html>

This does not work, but it might be a start. If copyCanvas() is called directly, without the setTimeout, I get a black picture with the right size in Chrome. I think this means that the canvas is still not drawn. With the delay, the canvas shows the picture, but I get an error saying that it cannot be converted with toBlob as it is tainted. This is explained here. You might avoid this taint if you can set the CORS policy in your server. I am still not sure about the portability of the solution.

You can simply copy the Base64 code after the ',' character to end (PHN2ZyB4bWxu...4=) and convert it to SVG using any services (like base64.guru) then copy the result to your clipboard as an image.

data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIiB3aWR0aD0iNDQ4IiBoZWlnaHQ9IjUxMiI+PHBhdGggZmlsbD0iIzNhNWI4NyIgZD0iTTAgNDY0YzAgMjYuNSAyMS41IDQ4IDQ4IDQ4aDM1MmMyNi41IDAgNDgtMjEuNSA0OC00OFYxOTJIMHYyNzJ6bTMyMC0xOTZjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTE5MiAyNjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJoLTQwYy02LjYgMC0xMi01LjQtMTItMTJ2LTQwem0wIDEyOGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMmgtNDBjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTY0IDI2OGMwLTYuNiA1LjQtMTIgMTItMTJoNDBjNi42IDAgMTIgNS40IDEyIDEydjQwYzAgNi42LTUuNCAxMi0xMiAxMkg3NmMtNi42IDAtMTItNS40LTEyLTEydi00MHptMCAxMjhjMC02LjYgNS40LTEyIDEyLTEyaDQwYzYuNiAwIDEyIDUuNCAxMiAxMnY0MGMwIDYuNi01LjQgMTItMTIgMTJINzZjLTYuNiAwLTEyLTUuNC0xMi0xMnYtNDB6TTQwMCA2NGgtNDhWMTZjMC04LjgtNy4yLTE2LTE2LTE2aC0zMmMtOC44IDAtMTYgNy4yLTE2IDE2djQ4SDE2MFYxNmMwLTguOC03LjItMTYtMTYtMTZoLTMyYy04LjggMC0xNiA3LjItMTYgMTZ2NDhINDhDMjEuNSA2NCAwIDg1LjUgMCAxMTJ2NDhoNDQ4di00OGMwLTI2LjUtMjEuNS00OC00OC00OHoiPjwvcGF0aD48L3N2Zz4=
Related