stop SVG feSpecularLighting filter from filling outside of a <rect> Element
I am developing in Chrome and Firefox and I've been having trouble with an SVG filter. when applied to a rect it seems to affect more than just the <rect>
element. Below is a screenshot of the result. As you can see it shades outside of the <rect>
which is undesired.
Below is the result in Chrome:
Below is the result in Firefox:
<?xml version="1.0" standalone="no"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head></head>
<body>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="100%" height="100%">
<defs>
<filter id="dropshadow" height="130%">
<feGaussianBlur in="SourceAlpha" stdDeviation="10"/>
<feOffset dx="5" dy="5" result="offsetblur"/>
<feMerge>
<feMergeNode/>
<feMergeNode in="SourceGraphic"/>
</feMerge>
<filter id = "I">
<feSpecularLighting specularExponent="2" lighting-color="#F3F4F3">
<fePoin开发者_如何学PythontLight x="300" y="100" z="100"/>
</feSpecularLighting>
</filter>
</filter>
</defs>
<rect x="33%" y="33%" rx="30" ry="30" width="33%" height="300px" style="fill:#FFFFFF; filter:url(#I)"></rect>
</svg>
</body>
</html>
This happens because the default filter effects region, as defined by the x
, y
, width
and height
parameters on the <filter>
element, is 120% of the bounding box of the filtered element, not 100%.
The specification clarifies:
It is often necessary to provide padding space because the filter effect might impact bits slightly outside the tight-fitting bounding box on a given object. For these purposes, it is possible to provide negative percentage values for ‘x’ and ‘y’, and percentages values greater than 100% for ‘width’ and ‘height’. This, for example, is why the defaults for the filter effects region are x="-10%" y="-10%" width="120%" height="120%".
Changing this to 100% would still affect the entire bounding box, though, so including the areas outside the rounded corners of the <rect>
. If you want to limit it to just the rectangle, you can use feComposite
. E.g.
<filter id="I">
<feSpecularLighting specularExponent="2" lighting-color="#F3F4F3" result="light">
<fePointLight x="300" y="100" z="100"/>
</feSpecularLighting>
<feComposite in="light" in2="SourceAlpha" operator="in" result="lit"/>
</filter>
Also, you've nested the #I
filter inside the #dropshadow
filter. That's not something you can do. Are you trying to combine the lighting and drop shadow? If so, you could do that like this:
<filter id="dropshadow">
<feSpecularLighting specularExponent="2" lighting-color="#F3F4F3" result="light">
<fePointLight x="300" y="100" z="100"/>
</feSpecularLighting>
<!-- Apply lighting inside rectangle -->
<feComposite in="light" in2="SourceAlpha" operator="in" result="lit"/>
<feGaussianBlur in="SourceAlpha" stdDeviation="10"/>
<feOffset dx="5" dy="5" result="blur"/>
<!-- Apply blur outside rectangle -->
<feComposite in="blur" in2="SourceAlpha" operator="out" result="shadow"/>
<!-- Combine lighting and shadow -->
<feComposite in="shadow" in2="lit" operator="xor" />
</filter>
This doesn't seem to work to work in Firefox, though, but then your original example doesn't work in Firefox for me either.
精彩评论