Search code examples
csssvgcss-animationsclipping

SVG clipping path not working correctly with CSS animation


The clipping path is animating along with the object I have masked out. I want the clipping path to remain where it is so that I can animate the objects underneath.

Here's how the image looks in Illustrator

It outputs properly in the browser. However, when I go to move the reflection position, the mask moves with it.

I have targeted the #Reflection ID, but it's also moving the clipping path.

<g>
    <defs>
        <path id="SVGID_7_" d="M775.58,676.03h69.62V552.34h-69.62V676.03z M871.16,552.34l0,123.69l69.63,0l0-123.69L871.16,552.34z
             M967.23,552.34l0,123.69l69.63,0l0-123.69L967.23,552.34z M1132.94,552.34l-69.63,0l0,123.69l69.63,0L1132.94,552.34z"/>
    </defs>

    <clipPath id="SVGID_8_">
        <use xlink:href="#SVGID_7_"  overflow="visible"/>
    </clipPath>

    <g id="Reflection" clip-path="url(#SVGID_8_)">
            <rect x="702.5" y="601.74" transform="matrix(0.395 -0.9187 0.9187 0.395 -81.7378 1094.6456)" fill="#FFFFFF" width="175.45" height="15.28"/>
            <rect x="732.3" y="601.74" transform="matrix(0.395 -0.9187 0.9187 0.395 -63.7121 1122.0173)" fill="#FFFFFF" width="175.45" height="15.28"/>
    </g>
</g>

Solution

  • You may wrap the rects in an extra g element and apply the transformation to that group. In the next example I'm using SMIL animations to do it:

    body{background:black;}
    #SVGID_7_{stroke:red; fill="none"}
    <svg viewBox = "740 520 130 180">
    <g>
        <defs>
            <path id="SVGID_7_" d="M775.58,676.03h69.62V552.34h-69.62V676.03z M871.16,552.34l0,123.69l69.63,0l0-123.69L871.16,552.34z
                 M967.23,552.34l0,123.69l69.63,0l0-123.69L967.23,552.34z M1132.94,552.34l-69.63,0l0,123.69l69.63,0L1132.94,552.34z"/>
        </defs>
    
        <clipPath id="SVGID_8_">
            <use xlink:href="#SVGID_7_" fill="black"/>
        </clipPath>
    <use xlink:href="#SVGID_7_"/>
        <g id="Reflection" clip-path="url(#SVGID_8_)">
          <g transform="translate(-80,0)">
                <rect x="702.5" y="601.74" transform="matrix(0.395 -0.9187 0.9187 0.395 -81.7378 1094.6456)" fill="#FFFFFF" width="175.45" height="15.28"/>
                <rect x="732.3" y="601.74" transform="matrix(0.395 -0.9187 0.9187 0.395 -63.7121 1122.0173)" fill="#FFFFFF" width="175.45" height="15.28"/>
            <animateTransform 
        	  attributeType="XML" 
            attributeName="transform" 
            type="translate"
            values="-80,0; 200,0" 
            calcMode="linear" 
            dur="4s" 
            repeatCount="indefinite" />
            </g>
        </g>
      
    </g>
    </svg>

    And the same example using css animations:

    body{background:black;}
    #SVGID_7_{stroke:red; fill="none"}
    
    #Reflection g{animation: anim 4s infinite;}
    
    @keyframes anim {   
         from { transform:translate(-80px,0)}   
         to   { transform:translate(200px,0)}  
      }
    <svg viewBox = "740 520 130 180">
    <g>
        <defs>
            <path id="SVGID_7_" d="M775.58,676.03h69.62V552.34h-69.62V676.03z M871.16,552.34l0,123.69l69.63,0l0-123.69L871.16,552.34z
                 M967.23,552.34l0,123.69l69.63,0l0-123.69L967.23,552.34z M1132.94,552.34l-69.63,0l0,123.69l69.63,0L1132.94,552.34z"/>
        </defs>
    
        <clipPath id="SVGID_8_">
            <use xlink:href="#SVGID_7_" fill="black"/>
        </clipPath>
    <use xlink:href="#SVGID_7_"/>
        <g id="Reflection" clip-path="url(#SVGID_8_)">
          <g>
                <rect x="702.5" y="601.74" transform="matrix(0.395 -0.9187 0.9187 0.395 -81.7378 1094.6456)" fill="#FFFFFF" width="175.45" height="15.28"/>
                <rect x="732.3" y="601.74" transform="matrix(0.395 -0.9187 0.9187 0.395 -63.7121 1122.0173)" fill="#FFFFFF" width="175.45" height="15.28"/>        
          </g>
        </g>
      
    </g>
    </svg>