Размытие форм 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 шт):
Все не так уж и элементарно. Чтобы это сработало, вам нужно немного сложить эти элементы друг на друга.
Вам понадобится маска, чтобы показать не размытый объект снаружи, и фильтр, чтобы показать его внутри обозначенной области.
Обеим нужны единицы, определенные как 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.)
