简体   繁体   中英

Rendering Dom Elements In Canvas

This is something of an odd issue. I am looking into the ability to prerender a textarea in a canvas to create an image. I started with a great article that leads me to believe all DOM elements can be rendered in the canvas. I adapted the code only slightly. This article can be found at: MDN (Mozilla Developer Network)

I have adapted that code example to allow for scaling of the svg and foriegnObject, as well as altering how the 'data' string is created. However, it is not rendering in the canvas and all my checks seem to indicate it should.

I might say that the example is out of date, or that my alterations might be the issue, but I'm not able to justify it. So, I am hoping someone might be able to point out why their fiddle runs properly, but mine does not.

I attempted to give a direct link to their fiddle, but it does not load the code (at least in preview). You will have to visit the MDN link to access it.

My Code

 var TC = { canvas: null, canvasContext: null, textarea: null, init: function () { TC.canvas = document.getElementById('c'); TC.canvasContext = TC.canvas.getContext('2d'); TC.textarea = document.getElementById('t'); var data = TC.createSVGImg(500, 500); document.getElementById('out').innerHTML = data; var DOMURL = window.URL || window.webkitURL || window; var img = new Image(); var svg = new Blob([data], { type: 'image/svg+xml;charset=utf-8' }); var url = DOMURL.createObjectURL(svg); img.onload = function () { TC.canvasContext.drawImage(img, 0, 0); DOMURL.revokeObjectURL(url); } img.src = url; }, createSVGImg: function (height, width) { var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="' + width + '" height="' + height + '"> [REPLACE] </svg>' var fo = '<foreignObject height="' + height + 'px" width="' + width + 'px"> [REPLACE] </foreignObject>' var d = '<div xmlns="http://www.w3.org/1999/xhtml"> [REPLACE] </div>' d = d.replace('[REPLACE]', TC.textarea.outerHTML); fo = fo.replace('[REPLACE]', d); svg = svg.replace('[REPLACE]', fo); return svg; } }; TC.init(); 
 <div> <canvas id="c" height="600" width="600" style="border:1px solid black"></canvas> <textarea rows="3" cols="20" style="color:white; text-shadow:0 0 2px blue; overflow:hidden;" id="t">This is a test&#10;This is only a test</textarea> <textarea id="out" rows="10" cols="80" style="overflow:hidden;"></textarea> </div> 

I am hoping someone can spot my failure, and that that incite might help someone else with a similar problem. Thanks.

Update. I changed the call to TC.createSVGImg to include the height and width in case the '%' is not allowed on the svg node, per the example code. It did not effect the outcome.

The problem is your svg is invalid.

copy paste the output of your svg to a file and open it in google-chrome or firefox and the svg is blank.

I manually edited your svg to make it renderable. This is what your svg should look like:

<svg xmlns="http://www.w3.org/2000/svg" width="500" height="500">  
<foreignObject width="500px" height="500px">
    <div xmlns="http://www.w3.org/1999/xhtml">
         <textarea rows="3" cols="20" style="color:white; text-shadow:0 0 2px blue; overflow:hidden;" id="t">This is a test This is only a test</textarea> 
    </div>
</foreignObject>
</svg>

Hope this will help. I changed the svg attributes values width and height to remove px. I also added a parent div with xmlns. Also I runned your javascript and it throws an exception on if (height && height.indexOf("px") < 0) { height += 'px'; } if (height && height.indexOf("px") < 0) { height += 'px'; } because height is passed as a int and int does not have the method indexOf (string do). You can see error in your javascript using the developper interface of most modern broswer. (f12 in chrome)

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