Passing computed SVG as a data URI to a SRC attribute

1.1k Views Asked by At

Have looked around the internet, and have not been able to find an answer to this.

I am building yet another custom image slider, but need to be able to handle arbitrary html in the div that is being animated.

Generally, this would be no problem... this certainly isn't the first slider I created, and, in general, if I require the pretty slice and dice effects, I use an empty div with the content as a background image like everyone else. If I do have to allow it to handle arbitrary html, I limit the effects, or simply fade in the html content once the slice-n-dice transition is completed.

In this case, however, I need the pretty effects AND the arbitrary HTML in the same sliders, and at the same time.

My best idea on how to do this was to convert the arbitrary HTML into an image.

I couldn't find a decent, client side solution anywhere... but eventually realized I could stuff the HTML into an SVG element, and can use SVG as a background image for the div.

(Just an FYI, this really only has to be handled by modern browsers, which can handle SVG and DATA-URLS and such)

The first part is actually kinda easy:

arbitraryHTML = "<style>div{padding:10px;border:5px solid red;border-radius:10px;width:500px;height:175px}p{text-align:justify;}img{height:50px;float:left;border-radius:5px;margin:10px;}</style><body><div><img src='steve.png'><h1>Arbitrary HTML</h1><p>This allows arbitrary HTML to be turned into an image, and the image is then able to be stuffed into a canvas.  In this case, I will leave this image as an image so that I can set it as a background image of a div that will be visually sliced apart for a slider.</div></body>";
var stuff = document.createElement('svg');
stuff.innerHTML = "<foreignObject>"+arbitraryHTML+"</foreignObject>";
document.body.appendChild(stuff);

This works perfectly fine if I just want to stuff it directly into the DOM... but what I need to do is to use it as a background image for the div that I am slicing and dicing.

Since I already have the SVG code, I should be able to use it as a data uri to feed the image in.

I found an example like this on fiddle, and attempted to use this method on the code sample above to stuff the svg into the background-image...So far, I have completely failed to do so.

Example:

var i = document.createElement('div');
i.setAttribute("style","background-image:url('data:image/svg+xml,<svg>"+stuff.innerHTML+"</svg>);'");
document.body.appendChild(i);

Every time, I get the same problem; there are no errors or warnings thrown by Chrome console, but the div simply shows completely empty.

Using some methods (the code sample above, for example) the console shows the data uri in the code for the div properly, but still fails to show the background.

As part of bug testing, I had both side by side... the actual svg element (which displayed fine), and the div with the same code stuck as a background image (which would not display). Due to this, I am assuming that my problem is something about the way I am casting the svg into the data-url rather than the svg itself.

I really haven't been playing with either inline SVG or Data URL's very much before this... so it is quite possible that I am handling the data URL's or SVG improperly for the way that I am trying to use them.

Not really sure what I am doing wrong, but would really like to solve this.

Is there a better way of converting arbitrary HTML into an image that I missed?

Or is my idea of how to achieve this on the right track, but the implementation screwed up?

Any help would be greatly appreciated.

1

There are 1 best solutions below

7
On BEST ANSWER

I guess Chrome still has this webkit bug. What your doing should work in Firefox or Opera 12. Note that IE9/10 doesn't support foreignObject at all, not sure about 11.