Ivan Ivan - 4 months ago 37
CSS Question

Clip-path and SVG rect inside animation

I am trying to make a fancy animation only in CSS. I started with a tutorial on W3 School and wanted to make it better. My idea is to have a square loader turning clockwise while another inside would turn in the opposite direction.

On this link you will see what I'm talking about, the only difference is that I would like the red part to be turning in the opposite direction.

In order to do so I tried adding another div with class name

.spinner
. Here's my try at it: https://jsfiddle.net/avhjj4ps/



.loader-container {
position: absolute;
left: calc(50% - 75px);
width: 150px;
height: 150px;
padding: 5px;
border: 1px solid red;
top: calc(50% - 75px);
}
img {
width: 200px;
margin: 20px;
/*animation: move 2s alternate infinite linear;*/
}

#myClip, #svg {
position: absolute;
left: 50%;
top: 50%;
}


.loader, .spinner {
position: absolute;

}
.loader {
left: calc(50% - 35px);
top: calc(50% - 35px);
width: 40px;
height: 40px;
border: 15px solid transparent;
border-top: 15px solid none;
/*-webkit-animation: loader 2s linear infinite;
animation: loader 2s linear infinite;*/
}
.spinner {
left: calc(50% - 55.1px);
top: calc(50% - 55.1px);
/*clip-path: url(#myClip);*/
width: 40px;
border-radius: 50%;
height: 40px;
border: 36px solid #f3f3f3;
border-top: 36px solid #5cb85c;
/*-webkit-animation: spin 2s linear infinite;
animation: spin 2s linear infinite;*/
}

@-webkit-keyframes loader {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(360deg); }
}

@keyframes loader {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

@-webkit-keyframes spin {
0% { -webkit-transform: rotate(0deg); }
100% { -webkit-transform: rotate(-360deg); }
}

@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(-360deg); }
}

<div class="loader-container">
<div class="loader"></div>
<div class="spinner"></div>

<svg id="svg" width="0" height="0">
<defs>
<clipPath id="myClip">
<rect x="-35" y="-35" width="15" height="70" />
<rect x="20" y="-35" width="15" height="70" />
<rect x="-35" y="-35" width="70" height="15" />
<rect x="-35" y="20" width="70" height="15" />

</clipPath>
</defs>
</svg>

</div>





I am trying to show the green spinner only where there is the square loader. It would be like a mask. In the above snippet (also available here: http://codepen.io/anon/pen/ZOoByA), I'm trying to use the clip-path property.
Can some tell me why
clip-path: url(#myClip);
doesn't work ? When I comment this line the loader shows completely, however while active it's not showing at all.

Answer

You need some helper elements:

<div class="loader">
    <div class="square"></div>
    <div class="cutter">
        <div class="spinner">
        </div>
    </div>
</div>

And then this CSS code:

.square {
  width: 40px;
  height: 40px;
  background: #f3f3f3;
  z-index: 1;
}

.cutter {
  width: 70px;
  height: 70px;
  left: -15px;
  top: -15px;
  overflow: hidden;
}

.spinner {
  width: 54px;
  border-radius: 50%;
  height: 54px;
  border: 8px solid transparent;
  border-top: 8px solid #5cb85c;
  -webkit-animation: spin 1s linear infinite;
  animation: spin 1s linear infinite;
  margin-left: -15px;
  margin-top: -15px;
}

Result: https://jsfiddle.net/avhjj4ps/3/