Comment copier le contenu d'un canevas vers un autre canevas localement

129

Je voudrais copier TOUS les contenus d'un canevas et les transférer dans un autre tout du côté client. Je pense que j'utiliserais la méthode canvas.toDataURL()et context.drawImage()pour implémenter cela, mais je rencontre quelques problèmes.

Ma solution serait d'obtenir Canvas.toDataURL()et de stocker cela dans un objet Image en Javascript, puis d'utiliser la context.drawImage()méthode pour le replacer.

Cependant, je pense que la toDataURLméthode renvoie une balise codée 64 bits avec "data:image/png;base64,"préfixe. Cela ne semble pas être une balise valide (je pourrais toujours utiliser du RegEx pour supprimer cela), mais est-ce que cette chaîne codée en 64 bits APRÈS la "data:image/png;base64,"sous - chaîne est une image valide? Puis-je dire image.src=iVBORw...ASASDASet dessiner ceci sur la toile?

J'ai examiné quelques problèmes connexes: Afficher l'image du canevas d'un canevas à un autre canevas en utilisant base64

Mais les solutions ne semblent pas correctes.

J Kao
la source

Réponses:

273

En fait, vous n'avez pas du tout besoin de créer une image. drawImage()acceptera un Canvasaussi bien qu'un Imageobjet.

//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);

Bien plus rapide que d'utiliser un ImageDataobjet ou un Imageélément.

Notez qu'il sourceCanvaspeut s'agir d'un HTMLImageElement , HTMLVideoElement ou d'un HTMLCanvasElement . Comme mentionné par Dave dans un commentaire sous cette réponse, vous ne pouvez pas utiliser un contexte de dessin de canevas comme source . Si vous avez un contexte de dessin de canevas au lieu de l’élément de canevas à partir duquel il a été créé, il y a une référence à l’élément de canevas original dans le contexte sous context.canvas.

Voici un jsPerf pour démontrer pourquoi c'est la seule bonne façon de cloner un canevas: http://jsperf.com/copying-a-canvas-element

Robert Hurst
la source
66
un petit point qui m'a fait trébucher: alors que vous pouvez dessiner un canevas ( HTMLCanvasElement), vous ne pouvez pas dessiner un contexte ( CanvasRenderingContext2D). Utilisez myContext.canvasplutôt.
Dave
3
Le commentaire @Dave est un DOIT LIRE ... woud donner +10 si possible;). @ Robert-Hurst doit compléter sa réponse avec ce commentaire car il ne précise pas d'où source canvasvient ...
Paulo Bueno
Pouvez-vous donner un exemple?
ShibinRagh
@RogerGajraj En fait, le canevas n'a pas besoin d'être visible. Ceci est démontré ici => jsfiddle.net/d36wwtvj
Robert Hurst
2

@ robert-hurst a une approche plus propre.

Cependant, cette solution peut également être utilisée dans les endroits où vous souhaitez réellement avoir une copie de l'URL de données après la copie. Par exemple, lorsque vous créez un site Web qui utilise de nombreuses opérations d'image / de canevas.

    // select canvas elements
    var sourceCanvas = document.getElementById("some-unique-id");
    var destCanvas = document.getElementsByClassName("some-class-selector")[0];

    //copy canvas by DataUrl
    var sourceImageData = sourceCanvas.toDataURL("image/png");
    var destCanvasContext = destCanvas.getContext('2d');

    var destinationImage = new Image;
    destinationImage.onload = function(){
      destCanvasContext.drawImage(destinationImage,0,0);
    };
    destinationImage.src = sourceImageData;
vishwarajanand
la source