简体   繁体   中英

Cloning canvas is not working

I am trying to clone the canvas element drawn by https://github.com/Kaiido/SVG2Bitmap/blob/master/SVG2Bitmap.js library, and it is not working. The library successfully creates and appends canvas element to html , but when I try cloning it, it just appends empty canvas elements. Here is the code I am trying to use:

let svg = d3.select("div#main svg").node();
let canvas = d3.select("#canvas0")
                    .append("canvas")
                    .attr("width", 500)
                    .attr("height", 500)
                    .node();
SVG2Bitmap(svg, canvas);
this.props.datum.map((clusterObj, idx) => {
  if (idx > 0) {
    let canvasId = "div#canvas" + idx;
    let clonedCanvas = this.canvasClone(canvas);
    d3.select(canvasId)
      .append(function() {
        return clonedCanvas;
      });
  }
})

Apparently I am selecting the correct div tags with d3 and appending canvas elements to them, but they are empty, nothing is drawn in them. canvasClone() function was taken from: Appending a div containing canvas is not working

And is:

function canvasClone(c1) {
  var c2 = document.createElement('canvas');
  c2.width=c1.width;
  c2.height=c1.height;
  c2.getContext("2d").drawImage(c1, 0,0);
  return c2;
}

The only warning message that I see in the console is:

在此处输入图片说明

Any suggestions would be greatly appreciated.

Update

I tried also:

let ctx =  c1.getContext("2d");
let imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
c2.getContext("2d").putImageData(imageData, 0, 0);

And nothing happens, not working

Update

I tried doing the following, considering that I can use the callback function, but it is still unsuccessfull:

let svg = d3.select("div#main svg").node();
SVG2Bitmap(svg, function(canvas) {
  this.props.datum.map((clusterObj, idx) => {
    let canvasId = "div#canvas" + idx;
    let clonedCanvas = this.canvasClone(canvas);
    d3.select(canvasId)
      .append(function() {
        return clonedCanvas;
      });
  })
});

That's my bad sorry, I made wrong design choices when writing this script...

The whole point of this script is to load all the external assets the svg element and its child do use in order to create a standalone document, drawable as is by drawImage method.

This means that the whole process will always be asynchronous, and hence my idea to pass something else than a callback function had very little sense, moreover when I didn't even allowed a way to pass both a receiver element and a callback function...

So first-of, sorry for my bad design choices in this now dead project. If I had to rewrite it (and maybe I will if I've got some time in the future), I would probably stick to fetching external assets and include it in the svg, letting the user choose what they want to do with it afterward.


But if you don't want to go through this ugly code yourself, you can workaround your issue quite easily.

The script does accept a callback function as receiver, on which the first argument will be a fresh <canvas> , with your svg already drawn on it.

 const this_props_datum = new Array(5).fill('foo'); let svg = d3.select("div#main svg").node(); SVG2Bitmap(svg, function callback(canvas) { this_props_datum.map((clusterObj, idx) => { let canvasId = "div#canvas" + idx; let clonedCanvas = this.canvasClone(canvas); d3.select(canvasId) .append(function() { return clonedCanvas; }); }) }); function canvasClone(c1) { var c2 = document.createElement('canvas'); c2.width = c1.width; c2.height = c1.height; c2.getContext("2d").drawImage(c1, 0, 0); return c2; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <script src="https://cdn.rawgit.com/Kaiido/SVG2Bitmap/a4ff9a91/SVG2Bitmap.min.js"></script> <div id="main"> <svg width=100 height=100 viewBox="0 0 40 40"> <circle cx=20 cy=20 r="20" fill="url(#patt)"/> </svg> </div> <div id="canvas0"></div> <div id="canvas1"></div> <div id="canvas2"></div> <div id="canvas3"></div> <div id="canvas4"></div> <!-- just to make the script useful... --> <svg width="0" height="0" style="position:aboslute;z-index:-1;opacity:0"> <defs> <pattern id="patt" x="0" y="0" width=".25" height=".25"> <image width="10" height="10" xlink:href="https://upload.wikimedia.org/wikipedia/commons/f/fd/Ghostscript_Tiger.svg"/> </pattern> </defs> </svg> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM