jQuery: How do I clone a div containing a p5 canvas?

偶尔善良 提交于 2019-12-11 07:45:29

问题


Using jQuery to clone a div:

$(document).ready(function() {
// clicking the buttton
  $(".showcanvas").click(function() {
// cloning and appending the div
    $(".canvas").first().clone(true).appendTo("article").fadeIn("1200");
    });
  });

with a p5 canvas inside that div:

<script>
  var sketch = function(p) {
     p.setup = function(){
       p.createCanvas(100, 100);
       p.background(0);
     }
   };
   new p5(sketch, 'drawing');
</script>

the div clones correctly but the p5 canvas is not there.

how do I clone the div so that the p5 canvas will be inside it?

https://jsfiddle.net/vanderhurk/xpvt214o/896958/

(click on "show canvas" button to see)


回答1:


Your canvas element is being cloned correctly. However, this will not clone any data written to the canvas.

If you wish to clone the state of the canvas without rerunning the code that generated it in the first place, you need to write the content of the original canvas to the newly created canvas.

$(document).ready(function() {
  $(".showcanvas").click(function() {
	
  // Find the original canvas element
  var origCanvas = $(".canvas").first().find('canvas');
  
  // Clone the div wrapper
  var clonedDiv = $(".canvas").first().clone(true);
  
  // Find the cloned canvas
  var clonedCanvas = clonedDiv.find('canvas');
  
  // Update the ID. (IDs should be unique in the document)
  clonedCanvas.prop('id', 'defaultCanvas' + $(".canvas").length)
  
  // Draw the original canvas to the cloned canvas
  clonedCanvas[0].getContext('2d').drawImage(origCanvas[0], 0, 0);
  
  // Append the cloned elements 
  // (Use .hide() before .fadeIn(). The duration should be a number, not a string)
  clonedDiv.appendTo("article").hide().fadeIn(1200);
    
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.7.2/addons/p5.dom.min.js"></script>

<article>
  <button class = "showcanvas">show canvas</button>

  <div class = "canvas">
    <div id = "drawing">
    hi
    </div>
  </div>
</article>

<script>
  var sketch = function(p) {
     p.setup = function(){
       p.createCanvas(100, 100);
       p.background(0);
     }
   };
   new p5(sketch, 'drawing');
</script>

Based on comments below, it does not seem to be possible to clone a canvas with its event handlers attached. To create a fully working canvas like your example I believe you would need to initialise a new instance of p5 for the cloned element.

Example: https://jsfiddle.net/3rror404/12fxj48h/40/




回答2:


It looks like when your canvas is cloned, it inherits the same ID as the original. I suspect that when the javascript is drawing to the canvas, it'll only find the first one with the given id and draw to that. Any others will be ignored. Try changing the id of each canvas on clone. You'll probably also need to let p5 know of the new canvases. I've forked your fiddle here with working cloning to demonstrate the issue; https://jsfiddle.net/12fxj48h/

 $(document).ready(function() { // clicking the buttton  
 $(".showcanvas").click(function() { // cloning and appending the div
    let clone = $(".canvas").first().clone();
    let cloned_canvas = clone.find("canvas");
    cloned_canvas.attr("id", "defaultCanvas1");

    clone.appendTo("article");
    new p5(sketch, 'drawing');      
  });  
});

UPDATE

In fact, it seems you don't need to update the ID (I'd still do it anyway). Just re-running p5 seems to work. https://jsfiddle.net/yfum1xjv/

$(document).ready(function() {
// clicking the buttton
  $(".showcanvas").click(function() {
// cloning and appending the div
    let clone = $(".canvas").first().clone();

    clone.appendTo("article");
    new p5(sketch, 'drawing');
    });
  });


来源:https://stackoverflow.com/questions/52931598/jquery-how-do-i-clone-a-div-containing-a-p5-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!