Scaling a fill pattern in raphael.js

后端 未结 2 1002
有刺的猬
有刺的猬 2021-02-02 04:15
paper=Raphael(\'previewBody\',480,480);
paper.path({\"stroke-width\":1},\'M0,0 L480,240 L480,480 L240,480 z\')
  .attr(\'fill\',\'url(bg.png)\'))
  .scale(.5,.5,0,0);


        
相关标签:
2条回答
  • 2021-02-02 04:32

    I don't know why but my version of Raphael library (I use newest) doesn't put ID as @ThibThib described. It's probably because we have 2013 now:)

    I will post my solution as well:

    <!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>
        </head>
        <body>
            <div id="raphael"></div>
            <script type="text/javascript">
                $(document).ready(function() {
    
                    var raphael, path, pattern;
    
                    raphael = Raphael(document.getElementById('raphael'), 500, 500);
    
                    path = raphael.circle(200, 200, 180);
                    path.attr('stroke', '#000000');
                    path.attr('stroke-width', 3);
                    path.attr('stroke-opacity', 1);
                    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
    
                    setTimeout(function() {
                        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);
                                path.attr('stroke', '#000000');
                                path.attr('stroke-width', 3);
                                path.attr('stroke-opacity', 1);
                            }
                        }
                        else { // SVG supported and it prints correct URL
                            $(pattern)[0].setAttribute('width', 50);
                            $(pattern)[0].setAttribute('height', 50);
                            $(pattern).find('image')[0].setAttribute('width', 50);
                            $(pattern).find('image')[0].setAttribute('height', 50);
                            $(pattern).find('image')[0].setAttribute('preserveAspectRatio', 'defer none meet');
                        }
                    }, 1000);
                });
            </script>
        </body>
    </html>
    

    Notice few things:

    • accessing VML fill image is described here: How to access Raphael fill image in VML

    • after changing size of image I had to reset stroke for VML version

    • for some reason jQuery .attr didn't work for me, so I used setAttribute (Chrome)

    • I set preserveAspectRatio to achieve same effect as in VML. You can disable it if you want to see differences (see documentation)

    • setTimeout is used to wait for image to be loaded, as SVG was setting params after image was loaded, and it was overwriting my size change

    You can of course play with different settings as well:

    VML Fill element documentation

    SVG Patterns

    SVG Image element

    0 讨论(0)
  • 2021-02-02 04:48

    It is note possible to do it by using only the functions of the raphael library.

    When you apply the scale function on a raphael's object, it creates a new svg node, with the coordinates scaled, but unfortunately, it doesn't modify the fill properties

    Anyway, when you add the attribute "fill" with an url, the library create a pattern. If it is the first "fill" attribute that you use, this pattern is called raphael-pattern-0 the next one is called raphael-pattern-1, etc...)

    Knowing this, it is then possible to change the attribute of the pattern, according to the SVG specifications

    You can get the attributes of the pattern with document.getElementById("raphael-pattern-0") and change its properties with the setAttribute For example (depending on what you really want to do), it could be something like:

    var pat = document.getElementById("raphael-pattern-0");
    pat.setAttribute("height", pat.getAttribute("height")*0.5);
    pat.setAttribute("width", pat.getAttribute("width")*0.5);
    

    You can also modify the x, y, patternUnits and patternContentUnits properties.

    Hope it will answer your question.

    0 讨论(0)
提交回复
热议问题