Question

I want to access VML element which stores fill image in VML. I pasted my demo code below. Notice that it will only work when you include raphael.js and jquery.js.

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <title>Raphael Test</title>

        <script type="text/javascript" src="js/libs/jquery.js"></script>
        <script type="text/javascript" src="js/libs/raphael.js"></script>
        <script type="text/javascript">
            $(document).ready(function() {

                var raphael, path, pattern;

                raphael = Raphael(document.getElementById('raphael'), 500, 500);

                path = raphael.circle(100, 100, 80);
                path.attr('stroke-width', 3);
                path.attr('fill', 'url(http://3.bp.blogspot.com/_M4WdA9j-b-g/TLMF9JJJwcI/AAAAAAAAAV4/p0Y_Wo3S3sQ/s1600/Landscape1.jpg)');
                pattern = $(path.node).attr('fill');
                if(pattern) {
                    pattern = pattern.replace('url(', '').replace(')', '');
                    pattern = $(pattern);
                }

                // Shape element documentation: http://msdn.microsoft.com/en-us/library/hh846327(v=vs.85).aspx#shape_element
                // Fill element documentation: http://msdn.microsoft.com/en-us/library/bb229596(v=vs.85).aspx

                if(Raphael.vml) { // SVG not supported (IE7 & IE8) and it doesn't work :/
                    console.log($(path.node).find('fill').attr('href'));
                }
                else { // SVG supported and it prints correct URL
                    console.log($(pattern).find('image').attr('href'));
                }
            });
        </script>

    </head>
    <body>
        <div id="raphael"></div>
    </body>
</html>

In SVG fill image is provided using pattern element. That's why I'm fetching this element, and I can easily access its href attribute.

VML is pretty different. Path is created with shape element, which have fill element inside. But unfortunately fill element doesn't have any attributes:/

Can someone help me to access VML fill image element?

Was it helpful?

Solution

I found the solution. I edited part of code above:

if(Raphael.vml) { // SVG not supported (IE7 & IE8) and it doesn't work :/

    var html = $(path.node).html();
    html = html.replace(/rvml:/g, ''); // remove prefix
    html = html.replace(/ = /g, '=');
    html = html.substr(html.indexOf('/>') + 2); // remove xml element

    var src = '';
    $(html).each(function() {
        if($(this).prop("tagName") == 'FILL') {
            src = $(this).attr('src');
        }
    });

    if(src != '') {
        var html = $(path.node).html();
        html = html.replace(src, src + '" size="50,50');
        $(path.node).html(html);
    }
}
else { // SVG supported and it prints correct URL
    console.log($(pattern).find('image').attr('href'));
}

First of all $(path.node).html() returns XML... So you need to parse it.

Another problem is that $.parseXML doesn't work for this XML... (IE7 and IE8) So I had to somehow parse it for myself (it's just quick solution - I'm sure you can parse it much better for production).

Last thing is that $(html) returns array of 6 elements (not 3!) because for some reason it treats closing tags separately. That's why I'm looping through $(html) set of elements and I'm searching for fill tag.

Biggest problem of this approach is that my solution is read only. You can't change source of the image and easily save it back... You cant easily change its size as well. You will have to change it in XML and save it back to path element, as it's on the end of example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top