在raphael.js中缩放填充图案

时间:2022-01-15 11:15:39
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);

My problem is the fill is not scaled with the svg canvas, so proportionally, it ends up as twice the size it was before the scale of the path. Is there any easy way to scale the fill pattern along with the rest of the svg?

我的问题是填充没有用svg画布缩放,因此按比例,它最终是路径缩放之前的两倍。有没有简单的方法来缩放填充模式以及svg的其余部分?

2 个解决方案

#1


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

需要注意的是,只使用raphael库的功能即可。

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

在raphael对象上应用缩放函数时,它会创建一个新的svg节点,其坐标已缩放,但不幸的是,它不会修改填充属性

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...)

无论如何,当您使用url添加属性“fill”时,库会创建一个模式。如果它是您使用的第一个“填充”属性,则此模式称为raphael-pattern-0,下一个称为raphael-pattern-1,等等...)

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

知道了这一点,就可以根据SVG规范更改模式的属性

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:

您可以使用document.getElementById(“raphael-pattern-0”)获取模式的属性,并使用setAttribute更改其属性例如(取决于您真正想要做的事情),它可能类似于:

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.

您还可以修改x,y,patternUnits和patternContentUnits属性。

Hope it will answer your question.

希望它能回答你的问题。

#2


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:)

我不知道为什么,但我的Raphael库版本(我用的是最新版本)没有把ID作为@ThibThib描述。这可能是因为我们现在有2013年:)

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

    访问VML填充图像如下所述:如何在VML中访问Raphael填充图像

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

    更改图像大小后,我不得不重置VML版本的笔划

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

    由于某种原因,jQuery .attr对我不起作用,所以我使用了setAttribute(Chrome)

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

    我设置preserveAspectRatio以达到与VML相同的效果。如果要查看差异,可以禁用它(请参阅文档)

  • 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

    setTimeout用于等待加载图像,因为SVG在加载图像后设置了参数,并且它覆盖了我的大小更改

You can of course play with different settings as well:

你当然可以玩不同的设置:

VML Fill element documentation

VML填充元素文档

SVG Patterns

SVG Image element

SVG图像元素

#1


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

需要注意的是,只使用raphael库的功能即可。

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

在raphael对象上应用缩放函数时,它会创建一个新的svg节点,其坐标已缩放,但不幸的是,它不会修改填充属性

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...)

无论如何,当您使用url添加属性“fill”时,库会创建一个模式。如果它是您使用的第一个“填充”属性,则此模式称为raphael-pattern-0,下一个称为raphael-pattern-1,等等...)

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

知道了这一点,就可以根据SVG规范更改模式的属性

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:

您可以使用document.getElementById(“raphael-pattern-0”)获取模式的属性,并使用setAttribute更改其属性例如(取决于您真正想要做的事情),它可能类似于:

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.

您还可以修改x,y,patternUnits和patternContentUnits属性。

Hope it will answer your question.

希望它能回答你的问题。

#2


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:)

我不知道为什么,但我的Raphael库版本(我用的是最新版本)没有把ID作为@ThibThib描述。这可能是因为我们现在有2013年:)

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

    访问VML填充图像如下所述:如何在VML中访问Raphael填充图像

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

    更改图像大小后,我不得不重置VML版本的笔划

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

    由于某种原因,jQuery .attr对我不起作用,所以我使用了setAttribute(Chrome)

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

    我设置preserveAspectRatio以达到与VML相同的效果。如果要查看差异,可以禁用它(请参阅文档)

  • 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

    setTimeout用于等待加载图像,因为SVG在加载图像后设置了参数,并且它覆盖了我的大小更改

You can of course play with different settings as well:

你当然可以玩不同的设置:

VML Fill element documentation

VML填充元素文档

SVG Patterns

SVG Image element

SVG图像元素