Any Way to Clone Html5 Canvas Element With Its Content

Any way to clone HTML5 canvas element with its content?

Actually the correct way to copy the canvas data is to pass the old canvas to the new blank canvas. Try this function.

function cloneCanvas(oldCanvas) {

//create a new canvas
var newCanvas = document.createElement('canvas');
var context = newCanvas.getContext('2d');

//set dimensions
newCanvas.width = oldCanvas.width;
newCanvas.height = oldCanvas.height;

//apply the old canvas to the new one
context.drawImage(oldCanvas, 0, 0);

//return the new canvas
return newCanvas;
}

Using getImageData is for pixel data access, not for copying canvases. Copying with it is very slow and hard on the browser. It should be avoided.

Possible to deep clone HTML5 canvas element with jQuery?

If you don't need to copy any attached event handlers (which, in general, I doubt is possible), I'd just use the currently accepted solution to Display canvas image from one canvas to another canvas using base64

//grab the context from your destination canvas
var destCtx = destinationCanvas.getContext('2d');

//call its drawImage() function passing it the source canvas directly
destCtx.drawImage(sourceCanvas, 0, 0);

Of course, you'd have to create the destination canvas first, so, before that, you'd have to:

var destinationCanvas    = document.createElement('canvas');
destinationCanvas.width = sourceCanvas.width;
destinationCanvas.height = sourceCanvas.height;

Duplicating a canvas many times: clone the canvas or copy the image data?

Cloning a canvas will duplicate its dimensions and styling, but not its image data. You can copy the image data by calling drawImage on the context. To paint the contents of originalCanvas onto duplicateCanvas, write:

duplicateCanvas.getContext('2d').drawImage(originalCanvas, 0, 0);

As a demonstration, the following snippet generates four canvases:

  • an original canvas with a small scene painted onto it

  • a copy made by calling cloneNode only

  • a copy made by calling cloneNode and drawImage

  • a copy made by creating a new image and setting its source to the data URI

function message(s) {  document.getElementById('message').innerHTML += s + '<br />';}
function timeIt(action, description, initializer) { var totalTime = 0, initializer = initializer || function () {}; initializer(); var startTime = performance.now(); action(); var elapsed = performance.now() - startTime; message('<span class="time"><span class="number">' + Math.round(elapsed * 1000) + ' μs</span></span> ' + description);}
function makeCanvas() { var canvas = document.createElement('canvas'), context = canvas.getContext('2d'); canvas.width = 100; canvas.height = 100; timeIt(function () { context.fillStyle = '#a63d3d'; context.fillRect(10, 10, 80, 40); // Paint a small scene. context.fillStyle = '#3b618c'; context.beginPath(); context.arc(60, 60, 25, 0, 2*Math.PI); context.closePath(); context.fill(); }, '(millionths of a second) to draw original scene', function () { context.clearRect(0, 0, canvas.width, canvas.height); }); return canvas;}
// copyCanvas returns a canvas containing the same image as the given canvas.function copyCanvas(original) { var copy; timeIt(function () { copy = original.cloneNode(); // Copy the canvas dimensions. copy.getContext('2d').drawImage(original, 0, 0); // Copy the image. }, 'to copy canvas with cloneNode and drawImage'); return copy;}
// imageFromStorage extracts the image data from a canvas, stores the image data// in a browser session, then retrieves the image data from the session and// makes a new image element out of it. We measure the total time to retrieve// the data and make the image.function imageFromStorage(original) { var image, dataURI = original.toDataURL(); timeIt(function () { image = document.createElement('img'); image.src = dataURI; }, 'to make image from a dataURI'); return image;}
function pageLoad() { var target = document.getElementById('canvases'), containers = {}, // We'll put the canvases inside divs. names = ['original', 'cloneNode', 'drawImage', 'dataURI']; for (var i = 0; i < names.length; ++i) { var name = names[i], // Use the name as an ID and a visible header. container = document.createElement('div'), header = document.createElement('div'); container.className = 'container'; header.className = 'header'; header.innerHTML = container.id = name; container.appendChild(header); target.appendChild(container); containers[name] = container; // The canvas container is ready. } var canvas = makeCanvas(); containers.original.appendChild(canvas); // Original canvas. containers.cloneNode.appendChild(canvas.cloneNode()); // cloneNode containers.drawImage.appendChild(copyCanvas(canvas)); // cloneNode + drawImage containers.dataURI.appendChild(imageFromStorage(canvas)); // localStorage}
pageLoad();
body {  font-family: sans-serif;}.header {  font-size: 18px;}.container {  margin: 10px;  display: inline-block;}canvas, img {  border: 1px solid #eee;}#message {  color: #666;  font-size: 16px;  line-height: 28px;}#message .time {  display: inline-block;  text-align: right;  width: 100px;}#message .number {  font-weight: bold;  padding: 1px 3px;  color: #222;  background: #efedd4;}
<div id="canvases"></div>
<div id="message"></div>

Can you clone contents of an element into canvas?

You can use html2canvas to do it, you can checkout the demo at this JSFiddle.

html2canvas(document.getElementById('clone-me'), {
onrendered: function(canvas) {
var canvas1 = document.getElementById('canvas1');
var ctx = canvas1.getContext('2d');
ctx.drawImage(canvas, 0, 0);
}
});

jQuery clone() does not clone content of canvas

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>

Duplicate/Clone HTML5 canvas in realtime

thanks, here is my code

var canvas = new fabric.Canvas('canvas');
var canvas2 = new fabric.StaticCanvas('canvas2');

// doing some stuffs on 'canvas'
(...)

// clonage into canvas2
var c=document.getElementById("canvas2");
var ctx=c.getContext("2d");
var fabricHtmlCanvasElement = document.getElementById('canvas');

canvas.on('after:render', function(options) {
updateCanvas();
});

function updateCanvas(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.drawImage(fabricHtmlCanvasElement,0,0);
}

it works perfectly thanks

How to Copy Contents of One Canvas to Another Canvas Locally

Actually you don't have to create an image at all. drawImage() will accept a Canvas as well as an Image object.

//grab the context from your destination canvas
var destCtx = destinationCanvas.getContext('2d');

//call its drawImage() function passing it the source canvas directly
destCtx.drawImage(sourceCanvas, 0, 0);

Way faster than using an ImageData object or Image element.

Note that sourceCanvas can be a HTMLImageElement, HTMLVideoElement, or a HTMLCanvasElement. As mentioned by Dave in a comment below this answer, you cannot use a canvas drawing context as your source. If you have a canvas drawing context instead of the canvas element it was created from, there is a reference to the original canvas element on the context under context.canvas.

Here is a jsPerf to demonstrate why this is the only right way to clone a canvas: http://jsperf.com/copying-a-canvas-element

Clone items when clicked (Html5-canvas)

I can't test this since I don't have your context, but I think all you need to do is put all the code dealing with the Clone inside the event listener, something like what I've done below.

This way, each event will create a new copy of Clone, and the conflicts you were experiencing should disappear.

item = new lib.item104();

this.addChild(item);
item.x = 250;
item.y = 350;
item.scaleX = item.scaleY = 1;

item.addEventListener("click", itemPressed.bind(this));

function itemPressed(evt) {
var Clone;
Clone = new lib.anim104();

this.addChild(Clone);
Clone.x = 250;
Clone.y = 200;
Clone.scaleX = Clone.scaleY = 1.5;
Clone.addEventListener("pressmove", dragClone.bind(this));
}

function dragClone(evt) {
var p = this.globalToLocal(evt.stageX, evt.stageY);
evt.currentTarget.x = p.x;
evt.currentTarget.y = p.y;
}


Related Topics



Leave a reply



Submit