Trying to draw SVG to canvas, why is my SVG XML getting truncated?

那年仲夏 提交于 2019-12-23 16:15:11

问题


All I really want to do is place my fancy dynamically created SVGs into a PDF, currently via jsPDF. addSVG doesn't work so I'm trying to convert them to PNG in order to try addImage instead.

This is in IE11 (client requirement).

If I do:

var lsvg = d3.select("#nowhere2").node().parentNode.innerHTML;
console.log(lsvg);

Maybe a third of the SVG shows up in the console. Odder, it truncates right in the middle of things so no ending tags or whatever:

<div id="nowhere2"><svg xmlns="http://www.w3.org/2000/svg" width="50px" height="800px"><defs><pattern id="oaghm" patternUnits="userSpaceOnUse" width="30" height="30"><path stroke="#343434" stroke-linecap="square" stroke-width="80" d="M 0 30 l 30 -30 M -7.5 7.5 l 15 -15 M 22.5 37.5 l 15 -15" shape-rendering="auto" /></pattern></defs><rect style="fill: url(#oaghm);" stroke="black" x="10" y="20" width="10" height="10" /><defs><pattern id="zpdff" patternUnits="userSpaceOnUse" width="4" height="4"><path stroke="#343434" stroke-linecap="square" stroke-width="1" d="M 0 4 l 4 -4 M -1 1 l 2 -2 M 3 5 l 2 -2" shape-rendering="auto" /></pattern></defs><rect style="fill: url(#zpdff);" stroke="black" x="10" y="40" width="10" height="10" /><defs><pattern id="dyxwi" patternUnits="userSpaceOnUse" width="10" height="10"><path stroke="#343434" stroke-linecap="square" stroke-width="2" d="M 0 10 l 10 -10 M -2.5 2.5 l 5 -5 M 7.5 12.5 l 5 -5" shape-rendering="auto" /><path stroke="#343434" stroke-linecap="square" stroke-width="2" d

Of course, this means my DataURI is broken, although Chrome tries valiantly (only used for testing, have to use IE11):

data:image/svg+xml;base64,PGRpdiBpZD0ibm93aGVyZTIiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iODAwIj48ZGVmcz48cGF0dGVybiBpZD0iZmRldWsiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjgwIiBkPSJNIDAgMzAgbCAzMCAtMzAgTSAtNy41IDcuNSBsIDE1IC0xNSBNIDIyLjUgMzcuNSBsIDE1IC0xNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZmRldWspOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InV2bWdnIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDQgbCA0IC00IE0gLTEgMSBsIDIgLTIgTSAzIDUgbCAyIC0yIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN1dm1nZyk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iNDAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD

Odder still, if I simply append the lsvg object back to the page, it renders just fine.

var lsvg = d3.select("#nowhere2").node().parentNode.innerHTML;
$("#nowhere").append(lsvg);

If I try to check it out in the console after appending I get the same truncated string. Of course, this leads me to believe that it's a timing/asynch issue, but I've tried every which way I can think of to get around that, including setting the draw-to-canvas-then-save-to-png function as a callback to my initial SVG draw function. I get the same oddly truncated string every time.

Here is my canvas (declared in html due to other issues):

<canvas id="lcanvas" width="50" height="800"></canvas>

Research led me to believe it could be a canvas/SVG size mismatch but that doesn't seem to be the case (what little I get of the SVG shows the same width/height, see above). Additionally it seems odd that it would truncate the initial string assignment before the canvas is even involved if that was true.

One glorious time I got a full DataURI:

data:image/svg+xml;base64,PGRpdiBpZD0ibm93aGVyZTIiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iODAwIj48ZGVmcz48cGF0dGVybiBpZD0iZmxhY3EiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjgwIiBkPSJNIDAgMzAgbCAzMCAtMzAgTSAtNy41IDcuNSBsIDE1IC0xNSBNIDIyLjUgMzcuNSBsIDE1IC0xNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZmxhY3EpOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InV5b3JkIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDQgbCA0IC00IE0gLTEgMSBsIDIgLTIgTSAzIDUgbCAyIC0yIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN1eW9yZCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iNDAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0iZ2VoYW8iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0gMCAxMCBsIDEwIC0xMCBNIC0yLjUgMi41IGwgNSAtNSBNIDcuNSAxMi41IGwgNSAtNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgMCBsIDEwIDEwIE0gLTIuNSA3LjUgbCA1IDUgTSA3LjUgLTIuNSBsIDUgNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZ2VoYW8pOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InZpYWNpIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN2aWFjaSk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iODAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0ic2d2eGoiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PGNpcmNsZSBmaWxsPSIjMzQzNDM0IiBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS13aWR0aD0iMCIgY3g9IjUiIGN5PSI1IiByPSI0IiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjc2d2eGopOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjEwMCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjxkZWZzPjxwYXR0ZXJuIGlkPSJybHFreCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIj48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSAwIDUgbCAxMCAwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNybHFreCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9Im1qbm5mIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDAgbCA1IDUgTSAtMS4yNSAzLjc1IGwgMi41IDIuNSBNIDMuNzUgLTEuMjUgbCAyLjUgMi41IiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNtam5uZik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTQwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImJseXJqIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNibHlyaik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImhieHVwIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48Y2lyY2xlIGZpbGw9IiMzNDM0MzQiIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLXdpZHRoPSIwIiBjeD0iMi41IiBjeT0iMi41IiByPSIyIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjaGJ4dXApOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjE4MCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjwvc3ZnPjwvZGl2Pg==

So I tested it using that DataURI explicitly, in other words no worrying about whether or not the drawing was already finished. I did:

limg.src = "data:image/svg+xml;base64,PGRpdiBpZD0ibm93aGVyZTIiPjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB3aWR0aD0iNTAiIGhlaWdodD0iODAwIj48ZGVmcz48cGF0dGVybiBpZD0iZmxhY3EiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjgwIiBkPSJNIDAgMzAgbCAzMCAtMzAgTSAtNy41IDcuNSBsIDE1IC0xNSBNIDIyLjUgMzcuNSBsIDE1IC0xNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZmxhY3EpOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InV5b3JkIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNCIgaGVpZ2h0PSI0Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDQgbCA0IC00IE0gLTEgMSBsIDIgLTIgTSAzIDUgbCAyIC0yIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN1eW9yZCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iNDAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0iZ2VoYW8iIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PHBhdGggc3Ryb2tlPSIjMzQzNDM0IiBzdHJva2UtbGluZWNhcD0ic3F1YXJlIiBzdHJva2Utd2lkdGg9IjIiIGQ9Ik0gMCAxMCBsIDEwIC0xMCBNIC0yLjUgMi41IGwgNSAtNSBNIDcuNSAxMi41IGwgNSAtNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgMCBsIDEwIDEwIE0gLTIuNSA3LjUgbCA1IDUgTSA3LjUgLTIuNSBsIDUgNSIgc2hhcGUtcmVuZGVyaW5nPSJhdXRvIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjZ2VoYW8pOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9InZpYWNpIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCN2aWFjaSk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iODAiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCIgLz48ZGVmcz48cGF0dGVybiBpZD0ic2d2eGoiIHBhdHRlcm5Vbml0cz0idXNlclNwYWNlT25Vc2UiIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PGNpcmNsZSBmaWxsPSIjMzQzNDM0IiBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS13aWR0aD0iMCIgY3g9IjUiIGN5PSI1IiByPSI0IiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjc2d2eGopOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjEwMCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjxkZWZzPjxwYXR0ZXJuIGlkPSJybHFreCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIj48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSAwIDUgbCAxMCAwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNybHFreCk7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTIwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9Im1qbm5mIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMSIgZD0iTSAwIDAgbCA1IDUgTSAtMS4yNSAzLjc1IGwgMi41IDIuNSBNIDMuNzUgLTEuMjUgbCAyLjUgMi41IiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNtam5uZik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTQwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImJseXJqIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiPjxwYXRoIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLXdpZHRoPSIyIiBkPSJNIDAgNSBsIDEwIDAiIHNoYXBlLXJlbmRlcmluZz0iYXV0byIgLz48cGF0aCBzdHJva2U9IiMzNDM0MzQiIHN0cm9rZS1saW5lY2FwPSJzcXVhcmUiIHN0cm9rZS13aWR0aD0iMiIgZD0iTSA1IDAgbCAwIDEwIiBzaGFwZS1yZW5kZXJpbmc9ImF1dG8iIC8+PC9wYXR0ZXJuPjwvZGVmcz48cmVjdCBzdHlsZT0iZmlsbDogdXJsKCNibHlyaik7IiBzdHJva2U9ImJsYWNrIiB4PSIxMCIgeT0iMTYwIiB3aWR0aD0iMTAiIGhlaWdodD0iMTAiIC8+PGRlZnM+PHBhdHRlcm4gaWQ9ImhieHVwIiBwYXR0ZXJuVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB3aWR0aD0iNSIgaGVpZ2h0PSI1Ij48Y2lyY2xlIGZpbGw9IiMzNDM0MzQiIHN0cm9rZT0iIzM0MzQzNCIgc3Ryb2tlLXdpZHRoPSIwIiBjeD0iMi41IiBjeT0iMi41IiByPSIyIiAvPjwvcGF0dGVybj48L2RlZnM+PHJlY3Qgc3R5bGU9ImZpbGw6IHVybCgjaGJ4dXApOyIgc3Ryb2tlPSJibGFjayIgeD0iMTAiIHk9IjE4MCIgd2lkdGg9IjEwIiBoZWlnaHQ9IjEwIiAvPjwvc3ZnPjwvZGl2Pg==";
console.log(limg.src);

And in the console was the same. blasted. truncated. string. Here is my code:

        var lsvg = d3.select("#nowhere2").node().parentNode.innerHTML;
        console.log(lsvg);

        var limg = new Image;
        var lcontext = canl.getContext('2d');

        limg.src = 'data:image/svg+xml;base64,' + btoa(lsvg);

        console.log(limg.src);
        lcontext.load = limg.addEventListener("load", function () {
            //console.log(limg.src);
            //This fun bit of code brought to you courtesy of IE11.
            try {
                lcontext.drawImage(limg, 0, 0);
            }
            catch (err) {
                setTimeout(lcontext.drawImage(limg, 0, 0), 0);
            };
            console.log(canl.toDataURL('image/png'));
        });

I left the canvas visible so I can see what sort of shenanigans might happen. It'll draw images from files just fine. Also, technically I get an image here, it's just blank and empty.

I don't want to draw from file because that taints the canvas and I get a security error on canl.toDataURL.

I have tried various ways of getting the lsvg bit, XMLSerialize, etc; all I get is a bit shorter head (no div element) and a bit longer tail before it's truncated after what seems to be the exact same number of characters. Right in the middle of things, as usual, so still no closing tags either, just an abrupt end mid-stream.

To be clear, this is not a cropped SVG. This is a 'clipped' SVG. Start tags, no end tags, broken image unless you're Chrome and you try rendering it anyway (IE doesn't even bother). The SVG is broken before the canvas is ever involved, and even independently of the drawing function after explicit assignment.

Oh sweet justice I have a fiddle! https://jsfiddle.net/94xhyv6t/ Try that in Chrome and IE and check out the console. In Chrome, if you click the link you'll get an XML page but you can see all the SVG elements there, in IE it is truncated.

Glad to know I'm not completely insane.

Just cuz I know someone will mention it, here's one without the parent DIV node: https://jsfiddle.net/94xhyv6t/1/ same issue.


edit: Note: this fiddle shows the issue: https://jsfiddle.net/94xhyv6t/1/ . Load it in Chrome, everything works. Load it in IE11, everything is truncated. I eliminated all other bits of code, this fiddle shows JUST the SVG string generation component and how it is truncated in IE. I have tried XMLSerializer per https://jsfiddle.net/94xhyv6t/4/ , same issue. Perhaps there's a workaround?


last edit for now: Console is simply truncating the display, the strings are fine otherwise. Accepted answer has a complete fiddle example showing how to get the SVG into the canvas, HOWEVER you cannot do canvas.toDataURL() in IE11 so this is not a suitable conversion method. I used canvg as a workaround.


回答1:


Don't know what your issue is exactly, but using

var data = new XMLSerializer().serializeToString(document.querySelector('svg'));
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(data);

works for me on FF and Chrome.

var n = 20, // number of layers
    m = 200, // number of samples per layer
    stack = d3.layout.stack().offset("wiggle"),
    layers0 = stack(d3.range(n).map(function() { return bumpLayer(m); })),
    layers1 = stack(d3.range(n).map(function() { return bumpLayer(m); }));

var width = 960,
    height = 500;

var x = d3.scale.linear()
    .domain([0, m - 1])
    .range([0, width]);

var y = d3.scale.linear()
    .domain([0, d3.max(layers0.concat(layers1), function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); })])
    .range([height, 0]);

var color = d3.scale.linear()
    .range(["#aad", "#556"]);

var area = d3.svg.area()
    .x(function(d) { return x(d.x); })
    .y0(function(d) { return y(d.y0); })
    .y1(function(d) { return y(d.y0 + d.y); });

var svg = d3.select("#worm").append("svg")
    .attr("width", width)
    .attr("height", height);

svg.selectAll("path")
    .data(layers0)
  .enter().append("path")
    .attr("d", area)
    .style("fill", function() { return color(Math.random()); });

function transition() {
  d3.selectAll("path")
      .data(function() {
        var d = layers1;
        layers1 = layers0;
        return layers0 = d;
      })
    .transition()
      .duration(2500)
      .attr("d", area);
}

// Inspired by Lee Byron's test data generator.
function bumpLayer(n) {

  function bump(a) {
    var x = 1 / (.1 + Math.random()),
        y = 2 * Math.random() - .5,
        z = 10 / (.1 + Math.random());
    for (var i = 0; i < n; i++) {
      var w = (i / n - y) * z;
      a[i] += x * Math.exp(-w * w);
    }
  }

  var a = [], i;
  for (i = 0; i < n; ++i) a[i] = 0;
  for (i = 0; i < 5; ++i) bump(a);
  return a.map(function(d, i) { return {x: i, y: Math.max(0, d)}; });
}
var lsvg = d3.select("#worm").node().parentNode.innerHTML;
console.log(lsvg);
var img = new Image;

console.log(img.src);
document.body.appendChild(img);
img.onload = function(){
	var canvas = document.createElement('canvas');
// IE seems to not set width and height for svg in img tag...
    canvas.width = this.width||960;
    canvas.height = this.height||500;
	canvas.getContext('2d').drawImage(this, 0,0);
    document.body.appendChild(canvas);
}
img.src = 'data:image/svg+xml; charset=utf8, ' + encodeURIComponent(new XMLSerializer().serializeToString(document.querySelector('svg')));
svg{border: 1px solid green}
img{border: 1px solid blue}
canvas{border: 1px solid red}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="worm"></div>

Note that I added the canvas stuff in the onload event of the img tag.

Edit : I found that IE doesn't set the width and height properties of svg loaded in <img> tags so you'll have to hard-code it or get it from the <svg> element



来源:https://stackoverflow.com/questions/32895732/trying-to-draw-svg-to-canvas-why-is-my-svg-xml-getting-truncated

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