Затухающий SVG-фильтр на фоновом изображении - PullRequest
0 голосов
/ 06 марта 2019

У меня есть коллекция элементов с фоновыми изображениями, на которых есть SVG-фильтр, делающий фоновое изображение сероватым.Мне нужно, чтобы при наведении указателя мыши на этот элемент SVG-фильтр стал прозрачным, чтобы исходное цветное изображение отображалось без фильтра.К сожалению, я не могу этого достичь.Вот CSS:

.badge__image {
    background-position: center;
    filter: url(/dist/filter.svg#duotone_bluetan);
}
.badge__image:hover {
    -webkit-transition : -webkit-filter 1000ms ease;
    transition: filter 1000ms ease;
    filter: url(/dist/filter.svg#clear);;
}

Независимо от того, как я это делаю, переход происходит мгновенно.Изображение должно быть фоновым, и мне нужно как-то выполнить этот переход фильтра SVG.Я не очень опытный с SVG фильтрацией или анимацией, и я не могу найти ни одного примера в Интернете, когда это делается.Любая помощь приветствуется.

РЕДАКТИРОВАТЬ

Так что я прикрепляю копию элемента внутри себя, позиционирую ее абсолютно и затемняю внутренний элемент.Это работает в одном направлении, оно исчезает на родительском фоне, однако, если не парить, непрозрачность внутреннего элемента мгновенно переходит на 1 без перехода.Что мне здесь не хватает?

.badge__image-filter {
    position: absolute;
    left: 0px;
    top: 0px;
    background-position: center;
    opacity: 1 !important;
    -webkit-transition: all 1000ms !important;
    transition: all 1000ms !important;
    filter: url(/dist/filter.svg#duotone_bluetan);
}
.badge__image-filter:hover {
    opacity: 0 !important;
    -webkit-transition: all 1000ms !important;
    transition: all 1000ms !important;
}

1 Ответ

2 голосов
/ 06 марта 2019

Здесь вы запрашиваете переход CSS с одного значения url() на другое. Что знает движок CSS, это просто строковые значения, которые не поддерживают переход.

Существуют различные способы достижения желаемого.

Одним из них будет дублирование вашего элемента, размещение обоих элементов и применение каждого фильтра к отдельному элементу, а затем передача обоих элементов opacity.

#clear,#filtered {
  position: absolute;
  top: 0;
  left: 0;
  transition: opacity 1s;
}
#filtered {
  filter: url(#blurMe);
}
#clear {
  opacity: 0;
}
#cont {
  position: relative;
}
#cont:hover #filtered {
  opacity: 0;
}
#cont:hover #clear {
  opacity: 1;
} 
<svg width="0" height="0" style="position:absolute;pointer-events:none">
  <filter id="blurMe">
    <feGaussianBlur in="SourceGraphic" stdDeviation="5">
    </feGaussianBlur>
  </filter>
</svg>
<div id="cont">
  <div id="filtered">Hello</div>
  <div id="clear">Hello</div>
</div>

Другой, в зависимости от вашего фактического фильтра, будет использовать SMIL внутри фильтра SVG:

#circ {
  filter: url(#blurMe);
}
<svg width="0" height="0" style="position:absolute;pointer-events:none">
  <filter id="blurMe">
    <feGaussianBlur in="SourceGraphic" stdDeviation="5">
      <animate attributeType="XML" attributeName="stdDeviation" to="0"
        dur="1s" fill="freeze" begin="circ.mouseover"/>
      <animate attributeType="XML" attributeName="stdDeviation" to="5"
        dur="1s" fill="freeze" begin="circ.mouseout"/>
    </feGaussianBlur>
  </filter>
</svg>

<div id="circ">Hello</div>

Но, похоже, это работает только в Firefox и Safari ...

И я должен отметить, что если вы можете преобразовать свой SVG-фильтр в чистый CSS-фильтр (используя только CSS ), то вы можете переходить через их значения, с одной ошибкой, которую вы должны поддерживать в порядке всех ваших фильтров между двумя состояниями; то есть вы не можете перейти с blur(5px) на sepia(100%), вы должны перейти с blur(5px) sepia(0) на blur(0) sepia(100%).

#circ {
  transition: filter 1s;
  color: red;
  filter: blur(5px) grayscale(100%);
}
#circ:hover {
  filter: blur(0px) grayscale(0);
}
<div id="circ">Hello</div>
...