Размытие форм SVG при прохождении по траектории обрезки (clipPath)

Пример ниже:

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

Я хотел бы сохранить фиксированную область в середине, через которую анимируются
круги svg.

Большинство примеров, которые я видел, включают какое-то слияние, в результате которого видны как исходный круг, так и размытая версия.
Примерно так:

<clipPath id="top-mask">
  <rect id="top-mask-rect" x="0" y="-100" width="100" height="100" />
</clipPath>

<filter id="top-blur" x="-200%" y="-200%" width="500%" height="500%">
  <feimage xlinkHref="url(#top-mask)" result="mask" />
  <feGaussianBlur stdDeviation="1.5" result="blur" />

  <feComposite in2="mask" in="blur" operator="in" result="comp" />

  <feMerge result="merge">
    <feMergeNode in="SourceGraphic" />
    <feMergeNode in="comp" />
  </feMerge>
</filter>

Круги накладываются поверх слегка размытой версии. Моим следующим шагом было удалить feComposite и вместо этого применить clipPath к обоим feMergeNode, что вообще не сработало.

Как правильно подойти к этой проблеме?

Свободный перевод вопроса Blurring svg shapes as they pass through clip path от участника @rbhalla.


Ответы (1 шт):

Автор решения: Alexandr_TT

Все не так уж и элементарно. Чтобы это сработало, вам нужно немного сложить эти элементы друг на друга.
Вам понадобится маска, чтобы показать не размытый объект снаружи, и фильтр, чтобы показать его внутри обозначенной области.
Обеим нужны единицы, определенные как userSpaceOnUse.

#moving {
  animation: move 5s ease-in-out infinite;
}
@keyframes move {
    0% { transform: translate(0px, 0px) }
   50% { transform: translate(300px, 0px) }
  100% { transform: translate(0px, 0px) }
}
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
     height="300" width="500">
  <defs>
  <mask id="mask"
        maskUnits="userSpaceOnUse">
    <rect width="100%" height="100%" fill="white" />
    <rect id="still" x="150" y="0" width="200" height="300" fill="black" />
  </mask>
    <filter id="blur" x="150" y="0" width="200" height="300"
            filterUnits="userSpaceOnUse">
      <feGaussianBlur stdDeviation="10" />
    </filter>
  </defs>
  <g mask="url(#mask)">
    <circle id="moving" r="60" cy="150" cx="100" fill="blue" />
  </g>
  <g filter="url(#blur)">
    <use xlink:href="#moving" />
  </g>
</svg>

Интересно, как работает фильтр. Кажется, что объект обрезается до применения размытия, что приводит к размытию около границы обозначенной области вместо резкого обрезания. Я не уверен, назвать это ошибкой или ожидаемым поведением. (Быстрый тест показал это как для Firefox, так и для Chrome.)

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

→ Ссылка