简体   繁体   中英

Why snapsvg mask doesn't work in Chrome and Firefox when there's a <base> tag in the header?

Here is my code

    var s = Snap("#mySVG");
    var r = s.rect(0,0,100,200,20,20).attr({ stroke: '#FFFFFF', 'strokeWidth': 20, fill: 'red' });
    var clip1 = s.rect(0,0,200,60).attr({ stroke: '#FFFFFF', 'strokeWidth': 1, fill: 'white' });
    r.attr({ mask: clip1 });

The mask works as expected in IE 10 but not in Firefox 32 and Chrome 37.

What is wrong ?

EDIT After user13500 answer. I turned the problem around, started with a blank page and import all elements from my non working page. It appears that a base tag in the header prevent it to work under FF and Chrome. That's looks crazy to me as everything else but masks works, so it's not a script path problem.

 <base href="http://127.0.0.1/mySiteDev/">

Yes, as commented by @Robert Longson , the masks url change with the base tag. You can reproduce the sample by plain HTML/SVG as:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Snap base</title>
<style media="screen">
body {
        background: #fff;
}
</style>
<base href="http://127.0.0.1/mySiteDev/">
</head>
<body>
<svg id="mySVG">
<defs>
    <mask id="Si0fh161e4">
        <rect x="0" y="0" width="200" height="60" stroke="#ffffff" 
              style="stroke-width: 1px;" fill="#ffffff">
        </rect>
    </mask>
</defs>
<rect x="0" y="0" width="100" height="200" rx="20" ry="20" stroke="#ffffff" 
      fill="#ff0000" style="stroke-width: 20px;" mask="url('#Si0fh161e4')">
<!--                                       Problem URL --^              -->
</rect>
</svg>
</body>
</html>

Here the url url('#Si0fh161e4') uses http://127.0.0.1/mySiteDev/ , to correct it one have to include document. Eg

mask="url('the_document.html#Si0fh161e4')"></rect>

or, the somewhat useless;

<base href="//127.0.0.1/mySiteDev/the_document.html">
<base href="the_document.html">
...

which defeats the usability

I have not found anything in the Snap documentation on setting base for URLs, but I'll look further.


Old answer:

Your code works fine here. Chrome 37, Firefox 32, Opera 12.

Result:

在此处输入图片说明


Sample snippet, (your code):

 window.onload = function () { var s = Snap("#mySVG"); var r = s.rect(0, 0, 100, 200, 20, 20).attr({ stroke : '#FFFFFF', strokeWidth : 20, fill : 'red' }); var clip1 = s.rect(0, 0, 200, 60).attr({ stroke : '#FFFFFF', strokeWidth : 1, fill : 'white' }); r.attr({ mask: clip1 }); }; 
 <script src="//cdnjs.cloudflare.com/ajax/libs/snap.svg/0.3.0/snap.svg-min.js"></script> <svg id="mySVG"></svg> 

I encountered this mask url() issue in AngularJS template which contained similar svg structure like in this jsfiddle . That worked fine until I noticed that it wasn't working in "search" page. I finally found this Stackoverflow thread and did some extra research, in my site base tag is always something like this

 <base href="/en/search/">

when you are in url "http ://example.com/en/search/?q=something"

In my AngularJS template I had to add "{{path}}" in to mask url. (check that fiddle for full svg)

<rect x="0" y="0"  width="48" height="47" fill="#008FDB" mask="url({{path}}#arrowShape)"></rect>

In my research I noticed that I only needed to add "window.location.search" in to that "path" variable and everything started to work also in "search" page. BUT 100% working version needed also some js logic, because I noticed that if your url is like "http ://example.com/en/?"

Internet Explorer will return "?" from "window.location.search". Chrome, Safari, Firefox and Opera will return just "" which is not enough to that svg mask to work.

$scope.path = '';
var tmp = $window.location.search;
if(tmp !== "") {
   $scope.path = tmp;
}
else if(/\?$/.test($window.location.href)) {
   $scope.path = '?';
}

After this svg mask started working consistently. (As a sidenote I have html5mode turned off.)

Here's the fix (in svg.js and dist files): https://github.com/adobe-webplatform/Snap.svg/issues/325

URL = Snap.url = function (url) {
    // return "url('#" + url + "')";
    return "url('" + window.location.pathname + "#" + url + "')";
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM