角度和SVG过滤器

Bla*_*ole 34 svg angularjs

在使用带有AngularJS的SVG时,我遇到了一个奇怪的行为.我正在使用该$routeProvider服务来配置我的路由.当我将这个简单的SVG放在我的模板中时,一切都很好:

<div id="my-template">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <rect fill="red" height="200" width="300" />
    </svg>
    // ...
</div>
Run Code Online (Sandbox Code Playgroud)

但是当我添加一个过滤器时,例如:

<div id="my-template">
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1">
        <defs>
            <filter id="blurred">
                <feGaussianBlur stdDeviation="5"/>
            </filter>
        </defs>
        <rect style="filter:url(#blurred)" fill="red" height="200" width="300" />
    </svg>
</div>
Run Code Online (Sandbox Code Playgroud)

然后:

  • 它适用于我的主页.
  • 使用Firefox,SVG 在其他页面上不再可见,但它仍然留有空间.使用Chrome,SVG可见,但根本不模糊.
  • 当我手动移除(使用Firebug)filter样式时,SVG再次可见.

这是路线配置:

$routeProvider
    .when('/site/other-page/', {
            templateUrl : 'view/Site/OtherPage.html',
            controller : 'Site.OtherPage'
    })
    .when('/', {
            templateUrl : 'view/Site/Home.html',
            controller : 'Site.Home'
    })
    .otherwise({
        redirectTo : '/'
    })
;
Run Code Online (Sandbox Code Playgroud)

Fiddle

请注意,虽然它可以与Firefox"一起使用",但我无法在小提琴中重现Chrome的问题.

我试图创建我的整个SVG无济于事document.createElementNS().

有人知道发生了什么吗?

Bla*_*ole 72

问题

问题是<base>我的HTML页面中有一个标记.因此,用于识别过滤器的IRI不再是相对于当前页面,而是<base>标签中指示的URL .

例如,该URL也是我的主页的URL http://example.com/my-folder/.

对于除主页之外的网页,http://example.com/my-folder/site/other-page/例如,#blurred在计算绝对URL http://example.com/my-folder/#blurred.但是对于一个简单的GET请求,没有JavaScript,因此没有AngularJS,这只是我的基页,没有加载模板.因此,此页面上不存在#blurred过滤器.

在这种情况下,Firefox不会呈现<rect>(这是正常行为,请参阅W3C推荐).Chrome根本不适用过滤器.

对于主页,#blurred也计算为绝对URL http://example.com/my-folder/#blurred.但这一次,这也是当前的URL.无需发送GET请求,因此存在#blurred过滤器.

我应该已经看到了额外的请求http://example.com/my-folder/,但在我的辩护中,它在JavaScript文件的大量其他请求中丢失了.

解决方案

如果<base>标记是必需的,则解决方案是使用绝对IRI来标识过滤器.在AngularJS的帮助下,这非常简单.在控制器或链接到SVG的指令中,注入$location服务并使用absUrl()getter:

$scope.absUrl = $location.absUrl();
Run Code Online (Sandbox Code Playgroud)

现在,在SVG中,只需使用此属性:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1">
    <defs>
        <filter id="blurred">
            <feGaussianBlur stdDeviation="5"/>
        </filter>
    </defs>
    <rect style="filter:url({{absUrl}}#blurred)" fill="red" height="200" width="300" />
</svg>
Run Code Online (Sandbox Code Playgroud)

相关: 当HTML页面中有BASE标记时,SVG Gradient变黑?