MortenMoulder
MortenMoulder

Reputation: 6646

jQuery clone() does not clone content of canvas

I'm trying to clone a page I need for printing. The print dialog should ONLY print out the selected element and its elements.

https://jsfiddle.net/ctqdhta7/

var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
ctx.font = "30px Arial";
ctx.fillText("Hello World", 10, 50);



setTimeout(function() {
  var restorepage = $('body').html();
  var printcontent = $("#hello").clone();
  $('body').empty().html(printcontent);
  window.print();
  $('body').html(restorepage);
}, 1000);

This copies the entire body page, clones the content of the print I should print out, then it empties the body and replaces it with the content it should print. After that, it opens the print dialog with ONLY the printable elements. A workaround could be: Create the whole canvas after .html(printcontent) once again. Since clone() only clones the HTML, the canvas has not been initialized and has no content.

Since I am using an Angular directive, I am unable to simply do the whole "redraw the canvas". Is there an Angular way that makes it possible to "re-render the DOM again" or something like that?

Upvotes: 0

Views: 1440

Answers (1)

Kaiido
Kaiido

Reputation: 136707

canvas "content" is not part of the DOM and can't be copied by DOM method. However, it's quite easy to call clonedCanvas.getContext('2d').drawImage(originalCanvas, 0,0) which will draw the original canvas on the cloned one.

You could then try something like

// This will override the HTMLCanvas 'cloneNode' prototype
(function(){
  var ori = HTMLCanvasElement.prototype.cloneNode;
  HTMLCanvasElement.prototype.cloneNode = function(){
    var copy = ori.apply(this, arguments);
    // don't do it for web-gl canvas
    if(this.getContext('2d')){
      copy.getContext('2d').drawImage(this, 0,0);
      }
    return copy;
    };
  })();

var original = document.querySelector('canvas');
original.getContext('2d').fillRect(20, 20, 20, 20);

for(var i = 0; i<20; i++){
  document.body.appendChild(original.cloneNode());
}
<canvas></canvas>

important note : The cloneNode method needs to be called on the canvas element directly (unfortunately, it won't work for canvas.parentNode.cloneNode(true)

Upvotes: 3

Related Questions