Reputation: 21
How can i "crop" the svg filter to fit the shape of the parent?
Right now I have a div as a circle, with an svg in it. But the svg filter creates an rectangel.
Edit: I tried to implement a wrapping div with border-radius:100% as suggested below, but then it removes the blur.
updated codepen with wrapping div
svg{
width:100%;
height: 100%;
}
.custom-cursor {
border-radius: 50%;
overflow: hidden;
width: 20px;
height: 20px;
background-image: conic-gradient( cyan, magenta, yellow, cyan);
filter: blur(5px) url("#blur-plus-grain");
}
<div class="custom-cursor">
<svg preserveAspectRatio="none">
<filter id="blur-plus-grain">
<feGaussianBlur stdDeviation="0.8" result="blur" />
<feTurbulence type="fractalNoise" numOctaves="26" baseFrequency="40" stitchTiles="stitch" result="grain" />
<feComposite operator="in" in="blur" in2="grain" />
</filter>
<circle fill="transparent" r="10" cx="50%" cy="50%" filter="url(#blur-plus-grain)" />
</svg>
</div>
Upvotes: 2
Views: 572
Reputation: 17240
You apply the svg noise-blur filter to your round gradient-filled div.
But there is still a css box context.
You actually need some padding to provide enough 'canvas' area. Otherwise any kind of blur might exceed for div elements boundaries:
* {
box-sizing: border-box;
}
svg {
width: 100%;
height: 100%;
}
.custom-cursor-clip {
width: 50px;
height: 50px;
padding:2%;
filter: url("#blur-plus-grain");
}
.custom-cursor {
width: 100%;
height: 100%;
border-radius: 100%;
background-image: conic-gradient(from 20deg, #003399, #74b4da, #e0bbd9);
}
<div class="custom-cursor-clip">
<div class="custom-cursor">
<svg preserveAspectRatio="none">
<filter id="blur-plus-grain">
<feGaussianBlur stdDeviation="4" result="blur" />
<feTurbulence type="fractalNoise" numOctaves="26" baseFrequency="40" stitchTiles="stitch" result="grain" />
<feComposite operator="in" in="blur" in2="grain" />
</filter>
</svg>
</div>
</div>
Edit:
Essentially you apply the conic gradient to the inner div.
The wrapping/outer div provides some padding as well as the svg-filter.
Edit 2:
You might also use the <foreignObject>
element for a more self-contained svg img asset:
<svg width="50" height="50" viewBox="0 0 100 100">
<style>
.conicGradient{
width: 100%;
height: 100%;
border-radius: 100%;
background-image: conic-gradient(from 20deg, #003399, #74b4da, #e0bbd9);
}
</style>
<filter id="blur-plus-grain" filterUnits="userSpaceOnUse" >
<feGaussianBlur stdDeviation="4" result="blur" />
<feTurbulence type="fractalNoise" numOctaves="26" baseFrequency="40" stitchTiles="stitch" result="grain" />
<feComposite operator="in" in="blur" in2="grain" />
</filter>
<foreignObject filter="url(#blur-plus-grain)"
x="10" y="10" width="80" height="80">
<div class="conicGradient" xmlns="http://www.w3.org/1999/xhtml" ></div>
</foreignObject>
</svg>
However, you still need some sort of padding/inner offset to prevent undesired cropping.
Upvotes: 1