Search code examples
htmlsvgsvg-filterssvg-animate

Animate feDropShadow inside filter


I have the following code and I want to animate feDropShadow inside defs

@import url("https://fonts.googleapis.com/css?family=Open+Sans:300&display=swap");

*,
*::before,
*::after {
	box-sizing: border-box;
	position: relative;
}

html,
body {
	padding: 0;
	margin: 0;
	width: 100%;
	height: 100%;
}

body {
	display: flex;
	justify-content: center;
	align-items: center;
	font-family: "Open Sans", sans-serif;
}

:root {
	--easing: cubic-bezier(0.87, 0.08, 0.23, 0.91);
	--duration: 0.3s;
	--pink: #770946;
}

#app {
	height: 100vh;
	width: 100%;
	background: #1e0238;
	position: relative;
	overflow: hidden;
}

.circle-pink {
	transform: scale(1);
	fill: none;
	stroke: var(--pink);
	stroke-width: 6;
}

.circle-fill {
	transform: scale(1);
	transform-origin: center center;
	fill: var(--pink);
	stroke: none;
	stroke-width: 0;
	filter: url(#shadow);
}
<div id='app'>
	<svg viewBox="0 0 100 100">
		<defs>
			<filter id="shadow">
				<feDropShadow id="shadow-appear" dx="-0.4" dy="0.4" stdDeviation="0.2" flood-opacity="0.25" />
			</filter>
			<animate xlink:href="shadow-appear" attributeName="dx" values="0;-0.4;0" dur="3s" />
			<animate xlink:href="shadow-appear" attributeName="dy" values="0;0.4;0" dur="3s" />
		</defs>
		<circle cx="50" cy="25" r="45" class="circle-pink" />
		<circle cx="50" cy="25" r="40" class="circle-pink" />
		<circle cx="50" cy="25" r="35" class="circle-pink" />
		<circle cx="50" cy="25" r="30" class="circle-pink" />
		<circle cx="50" cy="25" r="25" class="circle-pink" />
		<circle cx="50" cy="25" r="20" class="circle-pink" />
		<circle cx="50" cy="25" r="18" class="circle-pink circle-fill">
			<animate attributeName="r" values="18;20;18" dur="3s" repeatCount="indefinite" />
		</circle>
	</svg>
</div>

As per the MDN docs, these properties are animatable.

I want to achieve this animation using only SVG.

The radius is animating, but not the shadow.

I couldn't find any decent docs regarding this as well.

PS; I have already tried this pen and it didn't work in my case.


Solution

  • I have the following code and I want to animate feDropShadow inside defs

    To animate the feDropShadow filter, use the stdDeviation attribute

    <feDropShadow id="shadow-appear" dx="-0.4" dy="0.4" stdDeviation="0" flood-opacity="0.25" >
             <animate attributeName="stdDeviation" values="0;4;0" dur="2s" 
                  repeatCount="indefinite" /> 
    </feDropShadow>
    

    @import url("https://fonts.googleapis.com/css?family=Open+Sans:300&display=swap");
    
    *,
    *::before,
    *::after {
        box-sizing: border-box;
        position: relative;
    }
    
    html,
    body {
        padding: 0;
        margin: 0;
        width: 100%;
        height: 100%;
    }
    
    body {
        display: flex;
        justify-content: center;
        align-items: center;
        font-family: "Open Sans", sans-serif;
    }
    
    :root {
        --easing: cubic-bezier(0.87, 0.08, 0.23, 0.91);
        --duration: 0.3s;
        --pink: #770946;
    }
    
    #app {
        height: 100vh;
        width: 100%;
        background: #340362;
        position: relative;
        overflow: hidden;
    }
    
    .circle-pink {
        transform: scale(1);
        fill: none;
        stroke: var(--pink);
        stroke-width: 6;
    }
    
    .circle-fill  {
        transform: scale(1);
        transform-origin: center center;
        fill: var(--pink);
        stroke: none;
        stroke-width: 0;
        filter: url(#shadow); 
    }
    <div id='app'>
        <svg width="400" height="400" viewBox="0 -25 100 100">
            <defs>
                <filter id="shadow">
                    <feDropShadow id="shadow-appear" dx="-0.4" dy="0.4" stdDeviation="0" flood-opacity="0.25" >
    				  <animate attributeName="stdDeviation" values="0;4;0" dur="2s" repeatCount="indefinite" /> 
    				</feDropShadow>
                </filter>
                 <animate xlink:href="#shadow-appear" attributeName="dx" values="0;-0.4;0" dur="2s" /> 
                 <animate xlink:href="#shadow-appear" attributeName="dy" values="0;0.4;0" dur="2s" /> 
            </defs>
            <circle cx="50" cy="25" r="45" class="circle-pink" />
            <circle cx="50" cy="25" r="40" class="circle-pink" />
            <circle cx="50" cy="25" r="35" class="circle-pink" />
            <circle cx="50" cy="25" r="30" class="circle-pink" />
            <circle cx="50" cy="25" r="25" class="circle-pink" />
             <circle cx="50" cy="25" r="20" class="circle-pink" />
            <circle cx="50" cy="25" r="18" class="circle-pink circle-fill" >
                 
            </circle>
        </svg>
    </div>