zey
zey

Reputation: 6105

cannot draw my div innerHTML to canvas

This is my fiddle example .
In my code , I have three div ,first one has draggable and resizable text box , and second div acting like a preview .
I tried to convert this preview div's innerHTML to image using HTML 5 canvas .
I found this example and just trying like this .
I call drawImage function on the event of resizeEnd .
But I can make image for my preview div's innerHTML .
What's wrong in my code ?
How can I fix this ?

HTML

First<br/>

<div id="container">
    <div id="resizable" class="ui-widget-content">This is text Line 1<br/>
    This is text Line 1<br/>

    </div>
    <img src="http://www.psdgraphics.com/file/abstract-background.jpg" width="400" height="150" />
</div>

<br/>Second<br/>

<div id="previewContainer">
    <div id="previewText" xmlns='http://www.w3.org/1999/xhtml' class="ui-widget-content2">This is text Line 1<br/>
    This is text Line 1<br/>
</div>
    <img src="http://www.psdgraphics.com/file/abstract-background.jpg" width="400" height="150" />
</div>

<br/>
<canvas id="myCanvas" width="400" height="150" style="border:1px solid #d3d3d3;">

Javascript

var DEF_HEIGHT = 100; // the #resizable default height
var $preview = $('#previewText');

$("#resizable").resizable({
    containment: 'parent',
    handles: "se",
    aspectRatio: true,
    resize: function (event, ui) {
        var curHeight = (ui.size.height / DEF_HEIGHT) * 100;
        $(this).css('font-size', curHeight + '%');
    },
    stop: function (event, ui) {
        $preview.css({width: this.style.width, height: this.style.height, fontSize:this.style.fontSize});

      var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");

        var data = "<svg xmlns='http://www.w3.org/2000/svg' width='400' height='150'>" +
             "<foreignObject width='100%' height='100%'>" +               
document.getElementById('previewText').innerHTML +            
             "</foreignObject>" +
           "</svg>";

        var DOMURL = self.URL || self.webkitURL || self;
var img = new Image();
var svg = new Blob([data], {type: "image/svg+xml;charset=utf-8"});
var url = DOMURL.createObjectURL(svg);
       img.onload = function() {
    ctx.drawImage(img, 0, 0);
    DOMURL.revokeObjectURL(url);
};
img.src = url;

      //  var img = new Image();
//img.src = document.getElementById('previewText').innerHTML;
       // ctx.drawImage(img, 0, 0);
    }
})
.draggable({
    containment: 'parent',
    start: function () {},
    drag: function () {},
    stop: function (e, ui) {
        $preview.css($(this).position());
    }
});

Upvotes: 1

Views: 1765

Answers (1)

user1693593
user1693593

Reputation:

For some reason the <br/> tags seem to break the code. If you attached an error handler and printed the URL you would have seen for example:

img.onerror = function() {console.log(url)};

> blob:ffad7714-9640-46f4-b726-f056a93e5e8b

Paste that into the address bar and you can read the error message:

XML Parsing Error: mismatched tag. Expected: </br>. Location:
blob:ffad7714-9640-46f4-b726-f056a93e5e8b Line Number 5, Column 7:   
</div></foreignObject></svg>
------^

If you remove those br tags and replace them with p tags it will work:
Modified fiddle

I cannot give an answer as to why (I have looked at it several times and tried various combinations, even not self-closing versions but unless I missed something it seem to be an issue).

You can improve the code though: make sure quotes are the same - see for example the xmlns definition here (as you are merging strings):

<div id="..." xmlns='...' class="...">
        ^   ^       ^   ^       ^   ^

and if you intend to include the xml namespace specification in the div (which you must) you need to use outerHTML rather than innerHTML.

document.getElementById('previewText').outerHTML

That being said: There are numerous other limitations with SVG. Any external reference such as image, or css that reference an external image may prevent you from drawing the SVG. Everything has to be inline when using SVG with canvas.

Upvotes: 2

Related Questions