остановить фильтр SVG feSpecularLighting от заполнения вне элемента <rect> - PullRequest
3 голосов
/ 16 октября 2011

Я работаю в Chrome и Firefox, и у меня возникли проблемы с SVG-фильтром.при применении к прямоугольнику это влияет не только на элемент <rect>.Ниже приведен скриншот с результатом.Как вы можете видеть, он выходит за пределы <rect>, что нежелательно.

Ниже приведен результат в Chrome: undesired result in Chrome

Ниже приведен результат в Firefox: undesired result in FF

<?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">
<fePointLight 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>

1 Ответ

4 голосов
/ 16 октября 2011

Это происходит потому, что область эффектов фильтра по умолчанию , как определено параметрами x, y, width и height элемента <filter>, составляет 120% от ограничивающая рамка фильтруемого элемента, не 100%.

В спецификации уточняется:

Часто необходимо предусмотреть пространство для заполнения, поскольку эффект фильтра может слегка воздействовать на биты за пределами плотно прилегающей ограничительной рамки на данном объекте. Для этих целей можно предоставить отрицательные процентные значения для «x» и «y», а процентные значения больше 100% для «width» и «height». Именно поэтому, например, по умолчанию для области эффектов фильтра используются x = "- 10%" y = "- 10%" width = "120%" height = "120%".

Изменение этого значения до 100% все равно повлияет на всю ограничивающую рамку, включая области вне закругленных углов <rect>. Если вы хотите ограничить его только прямоугольником, вы можете использовать feComposite. Э.Г.

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

Кроме того, вы вложили фильтр #I в фильтр #dropshadow. Это не то, что вы можете сделать. Вы пытаетесь совместить освещение и тень? Если это так, вы можете сделать это так:

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

Это, похоже, не работает для Firefox, но тогда ваш оригинальный пример не работает и для Firefox для меня.

...