动画中的剪辑路径和 SVG 矩形

Clip-path and SVG rect inside animation

我只想在 CSS 中制作精美的动画。我从 W3 School 上的教程开始,并希望让它变得更好。我的想法是让一个正方形的装载机顺时针转动,而另一个在里面顺时针转动。

this link你会明白我在说什么,唯一的区别是我希望红色部分转向相反的方向。

为此,我尝试添加另一个 div,名称为 class .spinner。这是我的尝试: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>

我试图只在有方形加载器的地方显示绿色旋转器。它就像一个面具。在上面的代码片段中(也可在此处获得:http://codepen.io/anon/pen/ZOoByA),我正在尝试使用剪辑路径 属性。 有人能告诉我为什么 clip-path: url(#myClip); 不起作用吗?当我评论这一行时,加载程序完全显示,但是在活动时它根本不显示。

对于没有 SVG 的 CSS-only 解决方案,您需要一些辅助元素:

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

然后这个 CSS 代码:

.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;
}

结果:https://jsfiddle.net/avhjj4ps/3/

缺点:如果必须匹配parent/body 的背景,内部正方形必须有纯色背景(无渐变或图像)。

您可以使用 HTML 和 CSS 创建微调器,然后通过结合使用 clip-path 属性 和 svg <clipPath>元素。

你的html微调器结构:

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

现在将两个元素放在一起:

.loader {
  width: 40px;
  height: 40px;
  position: relative;
  left: 30px;
  top: 30px;
  border: 15px solid #dcdada;
  border-top: 15px solid none;
  -webkit-animation: loader 2s linear infinite;
  animation: loader 2s linear infinite;
}

.spinner {
  width: 0px;
  height: 0px;
  position: relative;
  left: -30px;
  top: -30px;
  border: 50px solid transparent;
  border-top: 50px solid #5cb85c;
  -webkit-animation: spin 1s linear infinite;
  animation: spin 1s linear infinite;
}

但是灰色边框内外仍然有绿色溢出。所以我们需要用 svg <polygon>.

把它剪掉
<svg height="0" width="0">
    <defs>
        <clipPath id="loaderClipper">
            <polygon points="0,0 0,70 70,70 70,0 0,0 15,15 55,15 55,55 15,55 15,15"/>
        </clipPath>
    </defs>
</svg>

这些点定义了一个 70x70 的正方形,并截断了一个 40x40 的正方形。

然后添加引用 svg <clipPath> 元素的 clip-path 属性:

.loader {
  clip-path: url(#loaderClipper);
}

Fiddle: https://jsfiddle.net/apLepsv3/2/

缺点:仅Firefox支持,不支持Chrome

您可以使用一些多边形在 svg 中创建加载器,然后使用 clipPath 将内部绿色加载器剪掉。

首先,将灰色边框定义为多边形:

<polygon id="loader" points="0,0 0,70 70,70 70,0 0,0 15,15 55,15 55,55 15,55 15,15" />

由于我们将重用这个形状(实际加载器和剪辑路径形状),我们将其放入 defs 标签中:

<svg height="0" width="0">
    <defs>
        <polygon id="loader" points="..." />
    </defs>
</svg>

然后我们把clipPath放到同一个defs标签中:

<clipPath id="loaderClipper">
    <use xlink:href="#loader" x="15" y="15" />
</clipPath>

15的偏移量是这样计算的:loader的宽度是70,旋转45度后宽度是70√2,四舍五入为100。右边是 (100 - 70) / 2 = 15.

实际使用的元素的 svg 如下所示:

<svg width="100" height="100" viewbox="0 0 100 100" clip-path="url(#loaderClipper)">
    <use xlink:href="#loader" class="loader" x="15" y="15" />
    <polygon class="spinner" points="0,0 100,0 50,50" x="30" y="30" />
</svg>

还有一些 css 用于颜色和动画:

svg {
  animation: rotate 2s linear infinite;
  transform-origin: 50px 50px;
}

.loader {
  fill: #dcdada;
}

.spinner {
  fill: #5cb85c;
  animation: rotate 1s linear infinite reverse;
  transform-origin: 50px 50px;
}

结果fiddle:https://jsfiddle.net/apLepsv3/10/

已在移动和桌面 Firefox 和 Chrome 上成功测试。