SVG: несколько эффектов в одном фильтре

Я пытаюсь внедрить несколько теней в один фильтр SVG, но полагаю, что мой вопрос носит более общий характер: как я могу добавить несколько эффектов в один фильтр SVG? В моем случае, вот конкретно то, что я пытаюсь сделать.

У меня есть документ SVG, который в настоящее время содержит один элемент пути, и я применил к этому элементу пути один эффект тени.

Мой документ SVG

 <svg xmlns:xlink="http://www.w3.org/1999/xlink" width="1440" height="1750">
      <defs>
        <filter id="dropshadow">
          <feGaussianBlur in="SourceAlpha" stdDeviation="2.2"></feGaussianBlur>
          <feOffset dx="12" dy="12" result="offsetblur"></feOffset>
          <feFlood flood-color="rgba(0,0,0,0.5)"></feFlood>
          <feComposite in2="offsetblur" operator="in"></feComposite>
          <feMerge>
            <feMergeNode></feMergeNode>
            <feMergeNode in="SourceGraphic"></feMergeNode>
          </feMerge>
        </filter>
      </defs>

      <path xmlns:xlink="http://www.w3.org/1999/xlink" d="M 100 100 L 300 100 L 200 300 z z" fill="#2DA9D6" filter="url(#dropshadow)"></path>
    </svg>

Что дает мне SVG, который выглядит так:

введите здесь описание изображения

Теперь я хочу добавить вторую (совершенно другую) тень к этому же элементу контура. Например, скажем, тень, которая идет вверх и влево от элемента. В CSS вся моя тень может выглядеть так:

box-shadow: 5px 5px 5px rgba(0,0,0,0.5), -5px -5px 5px rgba(0,0,0,0.5);

Как я могу сделать эти несколько теней с фильтрами SVG? Я просмотрел этот вопрос, который предлагает применить несколько эффектов в один фильтр, но я не знаю, как объединить несколько эффектов в один фильтр.

Спасибо за любую помощь!


person Nick Budden    schedule 31.03.2014    source источник


Ответы (2)


Вы можете использовать атрибуты result, чтобы дать имя выходным данным примитивного элемента фильтра, думайте об этом как о своего рода локальном атрибуте id фильтра. Затем вы можете использовать это имя в качестве входных данных фильтра с атрибутами in или in2.

<svg xmlns:xlink="http://www.w3.org/1999/xlink" width="1440" height="1750">
  <defs>
    <filter id="dropshadow">
     <feGaussianBlur in="SourceAlpha" stdDeviation="3" result="blur"/> 
      <feOffset dx="12" dy="12" result="offsetblur"/>
      <feOffset dx="-20" dy="-12" result="offsetblur2" in="blur"/>
      <feComponentTransfer result="shadow1" in="offsetblur">
        <feFuncA type="linear" slope="0.5"/>
      </feComponentTransfer>
      <feComponentTransfer result="shadow2" in="offsetblur2">
        <feFuncA type="linear" slope="0.2"/>
      </feComponentTransfer>
      <feMerge> 
        <feMergeNode in="shadow1"/>
        <feMergeNode in="shadow2"/>
        <feMergeNode in="SourceGraphic"/> 
      </feMerge>
    </filter>
  </defs>

  <path xmlns:xlink="http://www.w3.org/1999/xlink" d="M 100 100 L 300 100 L 200 300 z z" fill="#2DA9D6" filter="url(#dropshadow)"></path>
</svg>

См. скрипку.

person Erik Dahlström    schedule 31.03.2014
comment
Есть ли решение только для CSS, которое не требует дополнительной разметки SVG? - person tonejac; 18.10.2018

Вы можете сделать несколько фильтров, используя только CSS! Используйте функцию для каждого фильтра, разделенного пробелом:

.multiple-different-filters {
  filter: blur(20px) grayscale(20%);
}


.double-dropshadow {
  filter: drop-shadow(5px 5px 5px rgba(0,0,0,0.5)) drop-shadow(-5px -5px 5px rgba(0,0,0,0.5));

}

Вам нужно вызвать функцию drop-shadow() для каждой тени отдельно.

Из: https://css-tricks.com/almanac/properties/f/filter/

person karly    schedule 18.09.2020