问题
http://justplay.thefa.com uses raphael and svg to create masks for background images. You can see them under find football near you. the first has the heading: "To play or not to play".
These look great accross all desktop browsers and iOS 3.
Why are the images upside down in iOS 4?? anybody have any idea?
I've also created some simple examples at: http://the-taylors.org/teststation/raphael/v2.0/masks.html and http://jsfiddle.net/davetayls/5bWgX/1/
Thanks, been trying to work this out for ages... i'm completely baffled
回答1:
I came across the same issue. Apparently iOS uses a different coordinate system from desktops, and that leads to images being rendered upside down. Safari corrects this for most types of images, but not CSS fills.
My solution was to apply a scale(1,-1) transform to the pattern definition element that Raphael made. Note that I'm using Raphael 1.5.2 for this; however, I didn't see any relevant changes in 2.0 when I looked.
if (isIOS()) {
//iOS SVG fills use an upside-down coordinate system
var patternID = RaphaelElement[0].style.fill.replace('#', '')
var pattern = document.getElementById(patternID);
pattern.setAttribute("patternTransform", "scale(1, -1)");
}
Explanation:
Basically, you have 2 important HTML/SVG DOM elements:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="290" height="290">
<desc>Created with Raphaël</desc>
<defs>
<pattern id="r-11258319" patternTransform="scale(1, -1)">
<image />
</pattern>
</defs>
<path fill="url(#r-11258319)" style="fill: url("#r-11258319") rgb(0, 0, 0);" />
</svg>
(Unimportant SVG stuff removed)
The path
element is the element you have a Raphael reference to, and the pattern
element is the element you need to change. You need to add the patternTransform="scale(1, -1)"
attribute to the pattern
element. The two elements are only linked by the pattern's id, so I had to do a bit of hackery to extract this with .style.fill.replace('#', '')
.
回答2:
I used the answer above as a starting point, but in general style.fill isn't where to obtain the id for the pattern element, so below is a version which works better (in fact, you could use el.pattern.replace("pattern#", "")
to get the pattern id instead, but the approach below will work when passed in a raw SVG node or one wrapped in a Rapahael object)
function correctIpadSvgFill (el) {
el = el.nodeName ? el : el[0]
if (window.navigator.userAgent.indexOf("iPad") > -1) {
//iOS SVG fills use an upside-down coordinate system
var pattern,
attributes = el.attributes,
i,il;
for(i = 0, il = attributes.length; i < il; i++) {
if(attributes[i].name === "fill") {
pattern = document.getElementById(attributes[i].value.replace(/(url\(#|\))/g, ''));
pattern.setAttribute("patternTransform", "scale(1, -1)");
return pattern;
}
}
}
}
I find it's only really useful for repeating patterns though - the iPad's coordinate system is too broken to be able to precisely position single background images that display properly at all zoom levels.
来源:https://stackoverflow.com/questions/7663872/why-are-the-svg-image-fills-on-http-justplay-thefa-com-upside-down-in-ios4