Как добавить фильтр только к <image /> внутри SVG, но не ко всему SVG

119
23 марта 2022, 00:30

У меня небольшая проблема со стилизацией SVG и изображением внутри. В SVG у меня есть два фильтра.

  • Первый фильтр #innershadow применяется ко всему объекту SVG.
  • Второй фильтр я хочу применить только к изображению внутри, потому что эффект волны #turbulance портит весь объект SVG.

Эффект, которого я хочу добиться, это острые края с тенями внутри SVG и размытое изображение внутри (эффект SVG и #turbulance анимирован).

Возможно ли это?

.svg {
       filter:  url("#innershadow") url("#turbulence");
    }
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="0 0 2100 1500" class="svg" x="0px" y="0px">
        <filter id="innershadow" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur in="SourceAlpha" stdDeviation="10" result="blur"></feGaussianBlur>
          <feOffset dy="12" dx="12"></feOffset>
          <feComposite in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
          <feFlood flood-color="#444444" flood-opacity="0.75"></feFlood>
          <feComposite in2="shadowDiff" operator="in"></feComposite>
          <feComposite in2="SourceGraphic" operator="over" result="firstfilter"></feComposite>
          <feGaussianBlur in="firstfilter" stdDeviation="10" result="blur2"></feGaussianBlur>
          <feOffset dy="-12" dx="-12"></feOffset>
          <feComposite in2="firstfilter" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
          <feFlood flood-color="#444444" flood-opacity="0.75"></feFlood>
          <feComposite in2="shadowDiff" operator="in"></feComposite>
          <feComposite in2="firstfilter" operator="over"></feComposite>
        </filter>
        <filter id="turbulence" x="0" y="0" width="100%" height="100%">
          <feTurbulence id="sea-filter" numOctaves="0.1" seed="2" baseFrequency="0.02 0.05"></feTurbulence>
          <feDisplacementMap scale="20" in="SourceGraphic"></feDisplacementMap>
          <animate xlink:href="#sea-filter" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1" values="0.02 0.06;0.04 0.08;0.02 0.06" repeatCount="indefinite"/>
        </filter>
        <defs>
          <pattern id="img1"   patternUnits="userSpaceOnUse" x="0" y="0" height="100%" width="100%">
            <image xlink:href="https://i.stack.imgur.com/iC30t.jpg"  x="0" y="0" height="100%" width="100%" preserveAspectRatio="xMidYMid slice"/>
          </pattern>
        </defs>
        <path  fill="url(#img1)" filter="url(#innershadow); url(#turbulence)" >
          <animate  repeatCount="indefinite" attributeName="d" dur="5s"
                    values="M382,118c100.383-77.825,276.671,59.258,448,34,65.577-9.668,196.57-94.87,294-58,83.39,31.556,92.13,116.309,174,136,108.23,26.031,207.9-110.974,286-74,61.42,29.075,37.81,132.343,110,186,47.83,35.547,81.23,14.642,132,52,51.7,38.043,88.14,109.739,82,176-6.17,66.5-50.93,79.125-60,144-10.14,72.489,46.43,113.009,26,170-29.24,81.6-166.19,63.417-218,148-53.48,87.31,29.83,209.23-26,264-44.42,43.57-141.41-7.81-226,14-93.36,24.07-100.33,81.2-194,104-111.76,27.2-217.186-20.32-268-52-70.153-43.73-98.14-121.36-180-146-83.052-25-141.572,21.65-252,46-131.847,29.08-259.955,29.4-324-40-85.126-92.25,17.341-275.707-12-436-23.665-129.279-80.6-204.706-36-294,33.223-66.508,93.383-72.786,138-128C349.1,273.539,310,173.817,382,118Z;
                            M500,190c90.412-66.126,238.022,65.138,388,26,86.586-22.595,152.56-120.7,236-104,94.03,18.821,101.05,142.366,196,170,115.58,33.639,245.25-120.028,314-76,38.98,24.962,16.27,88.038,60,136,36.16,39.655,72.52,30.721,114,68,29.47,26.484,75.25,85.812,64,146-15.53,83.071-131.92,94.889-144,172-12.37,78.965,107.48,140.205,90,192-28.41,84.17-381.55,26.287-402,96-14.33,48.86,147.88,116.62,138,192-4.81,36.7-57.51,62.76-150,102-79.12,33.57-154.38,62.03-210,70-115.07,16.49-217.716-1.22-252-18-104.652-51.21-150.906-194.87-242-198-73.985-2.54-105.059,84.42-190,98-112.843,18.04-211.468-78.6-246-120-83.04-99.54-53.27-201.986-90-356-36.055-151.181-93.562-237.142-48-288,55.26-61.683,186.476,13.989,268-52C476.816,378.965,421.53,247.392,500,190Z;
                            M500,238C621.91,181.654,670.957,61.767,796,44c50.491-7.174,172,34.215,306,118,95.1,59.463,151.04,109.438,226,112,134.95,4.612,236.05-139.415,334-104,60.82,21.99,62.5,101.2,122,156,35.17,32.392,126.79,61.5,136,110,9.71,51.11-75.16,127.335-96,168-43.83,85.544-49.3,148.558-38,198,22.31,97.671,140.35,163.962,124,220-15.75,53.99-135.29,38.81-192,106-67.3,79.73-5.52,200.99-70,254-55.53,45.65-226.87-25.52-290-30-68.89-4.89-132.47,22.44-214-4-84.21-27.3-124.8-95.16-216-108-84.892-11.95-141.558,31.08-236,76-153.42,72.98-293.092,83.99-342,70-117.669-33.66-209.643-140.55-242-250-37.527-126.93,29.383-207.227,24-322C126.26,691.617,18.046,548.78,70,440c17.439-36.513,83.745-86.988,188-128C347.2,276.909,413.476,277.991,500,238Z;
                            M382,118c100.383-77.825,276.671,59.258,448,34,65.577-9.668,196.57-94.87,294-58,83.39,31.556,92.13,116.309,174,136,108.23,26.031,207.9-110.974,286-74,61.42,29.075,37.81,132.343,110,186,47.83,35.547,81.23,14.642,132,52,51.7,38.043,88.14,109.739,82,176-6.17,66.5-50.93,79.125-60,144-10.14,72.489,46.43,113.009,26,170-29.24,81.6-166.19,63.417-218,148-53.48,87.31,29.83,209.23-26,264-44.42,43.57-141.41-7.81-226,14-93.36,24.07-100.33,81.2-194,104-111.76,27.2-217.186-20.32-268-52-70.153-43.73-98.14-121.36-180-146-83.052-25-141.572,21.65-252,46-131.847,29.08-259.955,29.4-324-40-85.126-92.25,17.341-275.707-12-436-23.665-129.279-80.6-204.706-36-294,33.223-66.508,93.383-72.786,138-128C349.1,273.539,310,173.817,382,118Z "/>
        </path>
      </svg>

Необходимо убрать острые зубцы по краям:

Ожидаемый результат с гладкими краями:

Свободный перевод вопроса Add filter only to inside SVG, but not to the entire SVG от участника @mrKorny.

Answer 1

Поскольку, получаемый результат имеет острые края, фильтр #turbolence должен применяться только к заливке.

Чтобы добиться этого, форма и заливка должны быть на разных слоях: простое решение - создать <rect>, заполненный вашим изображением, и анимированную <mask> чтобы обрезать внешние острые края.
Таким образом, в CSS можно назначить каждый отдельный фильтр нужному элементу.

.svg {
  filter: url("#innershadow");
}
.svg .myfill {
  filter: url("#turbulence");
}
<svg xmlns="http://www.w3.org/2000/svg" width="100vw" height="100vh" viewBox="0 0 2100 1500" class="svg" x="0px" y="0px">
        <filter id="innershadow" x="-50%" y="-50%" width="200%" height="200%">
          <feGaussianBlur in="SourceAlpha" stdDeviation="10" result="blur"></feGaussianBlur>
          <feOffset dy="12" dx="12"></feOffset>
          <feComposite in2="SourceAlpha" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
          <feFlood flood-color="#444444" flood-opacity="0.75"></feFlood>
          <feComposite in2="shadowDiff" operator="in"></feComposite>
          <feComposite in2="SourceGraphic" operator="over" result="firstfilter"></feComposite>
          <feGaussianBlur in="firstfilter" stdDeviation="10" result="blur2"></feGaussianBlur>
          <feOffset dy="-12" dx="-12"></feOffset>
          <feComposite in2="firstfilter" operator="arithmetic" k2="-1" k3="1" result="shadowDiff"></feComposite>
          <feFlood flood-color="#444444" flood-opacity="0.75"></feFlood>
          <feComposite in2="shadowDiff" operator="in"></feComposite>
          <feComposite in2="firstfilter" operator="over"></feComposite>
        </filter>
        <filter id="turbulence" x="0" y="0" width="100%" height="100%">
          <feTurbulence id="sea-filter" numOctaves="0.1" seed="2" baseFrequency="0.02 0.05"></feTurbulence>
          <feDisplacementMap scale="20" in="SourceGraphic"></feDisplacementMap>
          <animate xlink:href="#sea-filter" attributeName="baseFrequency" dur="60s" keyTimes="0;0.5;1" values="0.02 0.06;0.04 0.08;0.02 0.06" repeatCount="indefinite"/>
        </filter>
        <defs>
          <pattern id="img1"   patternUnits="userSpaceOnUse" x="0" y="0" height="100%" width="100%">
            <image xlink:href="https://i.stack.imgur.com/iC30t.jpg"  x="0" y="0" height="100%" width="100%" preserveAspectRatio="xMidYMid slice"/>
          </pattern>
          <mask id="myMask">
            <path  fill="#fff">
              <animate  repeatCount="indefinite" attributeName="d" dur="5s"
                    values="M382,118c100.383-77.825,276.671,59.258,448,34,65.577-9.668,196.57-94.87,294-58,83.39,31.556,92.13,116.309,174,136,108.23,26.031,207.9-110.974,286-74,61.42,29.075,37.81,132.343,110,186,47.83,35.547,81.23,14.642,132,52,51.7,38.043,88.14,109.739,82,176-6.17,66.5-50.93,79.125-60,144-10.14,72.489,46.43,113.009,26,170-29.24,81.6-166.19,63.417-218,148-53.48,87.31,29.83,209.23-26,264-44.42,43.57-141.41-7.81-226,14-93.36,24.07-100.33,81.2-194,104-111.76,27.2-217.186-20.32-268-52-70.153-43.73-98.14-121.36-180-146-83.052-25-141.572,21.65-252,46-131.847,29.08-259.955,29.4-324-40-85.126-92.25,17.341-275.707-12-436-23.665-129.279-80.6-204.706-36-294,33.223-66.508,93.383-72.786,138-128C349.1,273.539,310,173.817,382,118Z;
                            M500,190c90.412-66.126,238.022,65.138,388,26,86.586-22.595,152.56-120.7,236-104,94.03,18.821,101.05,142.366,196,170,115.58,33.639,245.25-120.028,314-76,38.98,24.962,16.27,88.038,60,136,36.16,39.655,72.52,30.721,114,68,29.47,26.484,75.25,85.812,64,146-15.53,83.071-131.92,94.889-144,172-12.37,78.965,107.48,140.205,90,192-28.41,84.17-381.55,26.287-402,96-14.33,48.86,147.88,116.62,138,192-4.81,36.7-57.51,62.76-150,102-79.12,33.57-154.38,62.03-210,70-115.07,16.49-217.716-1.22-252-18-104.652-51.21-150.906-194.87-242-198-73.985-2.54-105.059,84.42-190,98-112.843,18.04-211.468-78.6-246-120-83.04-99.54-53.27-201.986-90-356-36.055-151.181-93.562-237.142-48-288,55.26-61.683,186.476,13.989,268-52C476.816,378.965,421.53,247.392,500,190Z;
                            M500,238C621.91,181.654,670.957,61.767,796,44c50.491-7.174,172,34.215,306,118,95.1,59.463,151.04,109.438,226,112,134.95,4.612,236.05-139.415,334-104,60.82,21.99,62.5,101.2,122,156,35.17,32.392,126.79,61.5,136,110,9.71,51.11-75.16,127.335-96,168-43.83,85.544-49.3,148.558-38,198,22.31,97.671,140.35,163.962,124,220-15.75,53.99-135.29,38.81-192,106-67.3,79.73-5.52,200.99-70,254-55.53,45.65-226.87-25.52-290-30-68.89-4.89-132.47,22.44-214-4-84.21-27.3-124.8-95.16-216-108-84.892-11.95-141.558,31.08-236,76-153.42,72.98-293.092,83.99-342,70-117.669-33.66-209.643-140.55-242-250-37.527-126.93,29.383-207.227,24-322C126.26,691.617,18.046,548.78,70,440c17.439-36.513,83.745-86.988,188-128C347.2,276.909,413.476,277.991,500,238Z;
                            M382,118c100.383-77.825,276.671,59.258,448,34,65.577-9.668,196.57-94.87,294-58,83.39,31.556,92.13,116.309,174,136,108.23,26.031,207.9-110.974,286-74,61.42,29.075,37.81,132.343,110,186,47.83,35.547,81.23,14.642,132,52,51.7,38.043,88.14,109.739,82,176-6.17,66.5-50.93,79.125-60,144-10.14,72.489,46.43,113.009,26,170-29.24,81.6-166.19,63.417-218,148-53.48,87.31,29.83,209.23-26,264-44.42,43.57-141.41-7.81-226,14-93.36,24.07-100.33,81.2-194,104-111.76,27.2-217.186-20.32-268-52-70.153-43.73-98.14-121.36-180-146-83.052-25-141.572,21.65-252,46-131.847,29.08-259.955,29.4-324-40-85.126-92.25,17.341-275.707-12-436-23.665-129.279-80.6-204.706-36-294,33.223-66.508,93.383-72.786,138-128C349.1,273.539,310,173.817,382,118Z "/>
            </path>
          </mask>
        </defs>
        <rect class="myfill" fill="url(#img1)" filter="url(#innershadow) url(#turbulence)" mask="url(#myMask)" width="2100" height="1500" ></rect>
          
 </svg>

Свободный перевод ответа от участника @thetont.

READ ALSO
Придание стилей одному элементу при наведении на другой

Придание стилей одному элементу при наведении на другой

Если использовать псeвдоэлемент :hover и прописать стили конкретному элементу, то эти стили будут применены к немуНо как сделать так, чтобы...

151
Фатальная ошибка

Фатальная ошибка

Есть у меня парсер музыки с ВК, так вот, он перестал работать, в чём может быть проблема?

90
Не работает фильтр array_filter php

Не работает фильтр array_filter php

Хочу от фильтровать массив, где есть значения "o" но что-то неправильно делаю, что надо изменить в коде? Чтоб массив отфильтровался и сохранял...

160
Повтор php скрипта

Повтор php скрипта

Есть крон, но он может запускать скрипт не чаще чем раз в минутуТак вот как сделать так, чтобы крон запускал скрипт, а он самоповторялся 5 раз...

113