0

I have a context menu, in which as User clicks the context menu button I start to render the html using html2canvas library, which returns a canvas using promise,

  function startCanvas(e) {


            CanvasPromise = html2canvas($TableDivCanvas.get(0), {

                height: html2canvasHeight + 20,
                width: html2canvasWidth + 20,

            });


        }

and when the the user clicks the copy option from the context menu, i have to upload the canvas returned from the promise to server, because if I put .dataurl() directly to image src, the copy command doesn't work (it returns false ). I also tried providing a blob url as image src but that also didn't work.

 $(document).on('click','.imageCopy',function(e){

            CanvasPromise.then(function (canvasElm) {
                    CanvasDataString = canvasElm.toDataURL("image/png", 1.0);

                    var urlHeading = Heading + Date.now() + ".png";
                    urlHeading = urlHeading.replace(/ +/g, "");

                    var formdata = new FormData();
                    formdata.append("base64image", CanvasDataString);
                    formdata.append("heading", urlHeading);
                    $.ajax({
                        url: "@Url.Action("SaveCanvas")",
                        type: "POST",
                        data: formdata,
                        processData: false,
                        contentType: false,
                        success: function (url) {

                        }   

                    });
                    url2 = document.location.origin + '/Upload/Images/' + urlHeading;

                    var img = document.createElement('img');
                    var div = document.createElement('div');
                    div.classList.add("CanvasimgDiv");
                    div.contentEditable = true;

                    div.appendChild(img);
                    img.src = url2;
                    document.body.appendChild(div);


                    try {

                        var selection = window.getSelection();
                        var range = document.createRange();
                        range.selectNodeContents($(".CanvasimgDiv").get(0));
                        selection.removeAllRanges();
                        selection.addRange(range);
                        var str = document.execCommand('copy');
                        console.log(str);
                        if (str == false) {
                            alert("Failed to copy image, Please close the menu and try again");
                        }
                        window.getSelection().removeAllRanges();
                        $('.CanvasimgDiv').remove();
                        $('.hiddClone').remove();

                    } catch (err) {
                        if (str == false) {
                            alert("Failed to copy image, Please close the menu and try again");
                        }
                        console.log(err);
                        $('.CanvasimgDiv').remove();

                    }
                })

The only problem I am having here is about time, if html2canvas take's more than 1 sec to render the canvas, the copy command fails.

  • What should be copied to clipboard in response to user action? How is the `$.ajax()` call related to copying data to the clipboard? – guest271314 Feb 25 '19 at 06:07
  • Screenshot of the screen (Image) should be copied to the clipboard, the ajax call upload's the image to the server. – Ibrahim Ali Asghar Feb 25 '19 at 06:11
  • If the issue is the 1 second window why is `$.ajax()` call and other code before `document.execCommand("copy")` call? See [Is there a way to select and copy an image to clipboard only with javascript commands?](https://stackoverflow.com/questions/41025469/is-there-a-way-to-select-and-copy-an-image-to-clipboard-only-with-javascript-com) – guest271314 Feb 25 '19 at 06:15
  • If `CanvasDataString` is the `data URL` of the screenshot why is the code between `CanvasDataString = canvasElm.toDataURL("image/png", 1.0);` and `try {} catch {}` necessary? – guest271314 Feb 25 '19 at 06:26
  • I have to upload the canvas returned from the promise to server, because if I put .todataurl() directly to image src, the copy command doesn't work (it returns false ). I also tried providing a blob URL as shown in your link which also returned false, with copying text you don't even need a blob URL, with images I think there are security restrictions that browsers only accept image from a URL as image src for copying to clipboard. (someone correct me if i am wrong) – Ibrahim Ali Asghar Feb 25 '19 at 06:27
  • The upload of the image to the server is not the problem statement at the question. Images can be copied to the clipboard, using several different approaches. – guest271314 Feb 25 '19 at 06:29
  • canvasElm is canvas variable, toDataURL provides a base64 string of the canvas to be uploaded on the server. – Ibrahim Ali Asghar Feb 25 '19 at 06:29
  • Yes, upload of image to the server is not the issue. Can you create a plnkr https://plnkr.co to demonstrate the issue. – guest271314 Feb 25 '19 at 06:31
  • Yes i know images can be clipboard, the problem is the time taken to create the image. – Ibrahim Ali Asghar Feb 25 '19 at 06:31
  • Can you reproduce the issue? Would first remove code between top of `.then()` and `try{}catch(){}`. Alternatives include drag and drop. `navigator.clipboard.writeText()` also available at modern browsers. – guest271314 Feb 25 '19 at 06:38
  • https://plnkr.co/edit/uEJLHd401YOPOeisAoRV?p=preview – guest271314 Feb 25 '19 at 06:47

1 Answers1

0

You can use navigator.clipboard.writeText() to write a data URL to the clipboard following asynchronous code within a handler dispatched following user action.

guest271314
  • 1
  • 15
  • 104
  • 177