Search code examples
animationsvgloadersvg-animate

SVG animation: scale multiple figures from their respective origin in a single .svg file


I want to have a loader with three pulsating and fading stars. I already created this loader with CSS, but this technique is not appropriate for this case. I want to have a single loader.svg file.

Here is a pen with the CSS version:

https://codepen.io/Joan_Na/pen/wvawzEb This is what it should look like.

Here is my approach for the single SVG file:

https://codepen.io/Joan_Na/pen/gOpYwNy I can't get the stars scaling from their respective origins. It would also be nice to start the animation of each star seperately, like in the CSS example above.

Here is the SVG file code:

<div class="container">
<svg width="90px" height="30px" viewBox="0 0 90 30" xmlns="http://www.w3.org/2000/svg">
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="44.9437" y1="-0.0694" x2="45.0305" y2="19.8832">
	<stop  offset="0.155" style="stop-color:#FEFE7B"/>
	<stop  offset="0.2795" style="stop-color:#FEFC75"/>
	<stop  offset="0.4527" style="stop-color:#FEF663"/>
	<stop  offset="0.6546" style="stop-color:#FEED45"/>
	<stop  offset="0.8763" style="stop-color:#FDE01C"/>
	<stop  offset="1" style="stop-color:#FDD802"/>
</linearGradient>
	<polygon id="star1" fill="url(#SVGID_1_)" points="45,6 47.93,11.92 54.47,12.87 49.73,17.49 50.85,24 45,20.93 39.15,24 40.27,17.49 
		35.53,12.87 42.07,11.92" transform="translate(-30 0)"/>
		<animateTransform
			attributeName="transform" 
			attributeType="XML" 
			type="scale"
			dur="1s" 
			values="1;0;1"
			repeatCount="indefinite" 
			begin="0s"  
			calcMode="linear"/>
		<animate
			attributeName="opacity"
			values="1;0;1" 
			dur="1s"
			repeatCount="indefinite" 
			begin="0s" 
			calcMode="linear"/>
<polygon id="star2" fill="url(#SVGID_1_)" points="45,6 47.93,11.92 54.47,12.87 49.73,17.49 50.85,24 45,20.93 39.15,24 40.27,17.49 
	35.53,12.87 42.07,11.92 " transform="translate(0 0)"/>
	<animateTransform
			attributeName="transform" 
			attributeType="XML" 
			type="scale"
			dur="1s" 
			values="1;0;1"
			repeatCount="indefinite" 
			begin="0s"  
			calcMode="linear"/>
		<animate
			attributeName="opacity"
			values="1;0;1" 
			dur="1s"
			repeatCount="indefinite" 
			begin="0s" 
			calcMode="linear"/>
<polygon id="star3" fill="url(#SVGID_1_)" points="45,6 47.93,11.92 54.47,12.87 49.73,17.49 50.85,24 45,20.93 39.15,24 40.27,17.49 
	35.53,12.87 42.07,11.92 " transform="translate(30 0)"/>
	<animateTransform
			attributeName="transform" 
			attributeType="XML" 
			type="scale"
			dur="1s" 
			values="1;0;1"
			repeatCount="indefinite" 
			begin="0s"  
			calcMode="linear"/>
		<animate
			attributeName="opacity"
			values="1;0;1" 
			dur="1s"
			repeatCount="indefinite" 
			begin="0s"
			calcMode="linear" />

</svg>
</div>


Solution

  • To prevent the stars from shifting during the scale () transform, I applied CSS rules

    #star1, #star2, #star3  {
    transform-origin: center;
    transform-box:fill-box;
    }
    

    Since this CSS rule does not work together with the SVG transformation command transform =" translate ()" I had to use my own separate path for each star.

    .container {
    background:#000;
    width:30vw;
    height:15vh;
    padding-left:30px;
    }
    <div class="container">
    <svg xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" width="90" height="30" viewBox="0 0 90 30" version="1.1">
    
    <linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="44.9437" y1="-0.0694" x2="45.0305" y2="19.8832">
    	<stop  offset="0.155" style="stop-color:#FEFE7B"/>
    	<stop  offset="0.2795" style="stop-color:#FEFC75"/>
    	<stop  offset="0.4527" style="stop-color:#FEF663"/>
    	<stop  offset="0.6546" style="stop-color:#FEED45"/>
    	<stop  offset="0.8763" style="stop-color:#FDE01C"/>
    	<stop  offset="1" style="stop-color:#FDD802"/>
    </linearGradient> 
     <path id="star1" fill="url(#SVGID_1_)" d="m 20.9062,24.304922 -5.85,-3.07 -5.85,3.07 1.12,-6.51 -4.74,-4.62 6.54,-0.95 2.93,-5.9200004 2.93,5.9200004 6.54,0.95 -4.74,4.62 z" style="transform-origin: center; transform-box:fill-box;" >
          <animateTransform id="an_T1"
    			attributeName="transform" 
    			attributeType="XML" 
    			type="scale"
    			dur="1s" 
    			values="1;0;1"
    			repeatCount="indefinite" 
    			begin="0s"
          keyTimes="0;0.75;1"
          />
    		<animate id="an_Op1"
    			attributeName="opacity"
    			values="1;0;1" 
    			dur="1s"
    			repeatCount="indefinite" 
    			begin="0s"
          keyTimes="0;0.75;1"
          /> 
     </path>
     
     
    
     <path id="star2"  fill="url(#SVGID_1_)" d="M 54.47,12.87 49.73,17.49 50.85,24 45,20.93 39.15,24 40.27,17.49 35.53,12.87 42.07,11.92 45,6 l 2.93,5.92 z" style="transform-origin: center; transform-box:fill-box;" >
          <animateTransform id="an_T2"
    			attributeName="transform" 
    			attributeType="XML" 
    			type="scale"
    			dur="1s" 
    			values="1;0;1"
    			repeatCount="indefinite" 
    			begin="0.2s"
          keyTimes="0;0.75;1"
          />
    		<animate id="an_Op2"
    			attributeName="opacity"
    			values="1;0;1" 
    			dur="1s"
    			repeatCount="indefinite" 
    			begin="0.2s"
          keyTimes="0;0.75;1"
          /> 
     </path> 
    
    
    
      <path id="star3" fill="url(#SVGID_1_)" d="m 79.700565,18.010534 1.12,6.51 -5.85,-3.07 -5.85,3.07 1.12,-6.51 -4.74,-4.62 6.54,-0.95 2.93,-5.9200003 2.93,5.9200003 6.54,0.95 z" style="transform-origin: center; transform-box:fill-box;" >
        <animateTransform id="an_T3"
    			attributeName="transform" 
    			attributeType="XML" 
    			type="scale"
    			dur="1s" 
    			values="1;0;1"
    			repeatCount="indefinite" 
    			begin="0.4s"  
    			keyTimes="0;0.75;1"/>
    		<animate id="an_Op3"
    			attributeName="opacity"
    			values="1;0;1" 
    			dur="1s"
    			repeatCount="indefinite" 
    			begin="0.4s"
    			keyTimes="0;0.75;1"	 
    			/> 
     </path> 
      
    </svg>
    </div>

    Update

    According to the remark in the comment, moved the styles inside svg