下面的例子:
我想在中间保留一个固定区域,circle通过它来设置 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>
Run Code Online (Sandbox Code Playgroud)
这似乎将圆圈覆盖在略微模糊的版本之上。我的下一个天真的步骤是删除feComposite,而是应用于根本不起作用的clipPath两者feMergeNode。
解决这个问题的正确方法是什么?
事情不是那么基本。你必须把东西堆在一起才能工作。您需要一个遮罩以将未模糊的对象显示在外面,并需要一个过滤器将其显示在指定区域内。两者都需要定义为 的单位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) }
}Run Code Online (Sandbox Code Playgroud)
<?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>Run Code Online (Sandbox Code Playgroud)
过滤器的工作方式很有趣。对象似乎在应用模糊之前被裁剪,导致指定区域边界附近出现模糊而不是硬剪切。我不确定是否将此称为错误或预期行为。(快速测试显示了 Firefox 和 Chrome 的这一点。)