【问题标题】:Clip-path and SVG rect inside animation动画中的剪辑路径和 SVG 矩形
【发布时间】:2016-11-27 04:28:01
【问题描述】:

我正在尝试仅在 CSS 中制作精美的动画。我从 W3 School 的教程开始,想把它做得更好。我的想法是让一个方形装载机顺时针转动,而另一个内部则向相反方向转动。

this 链接上你会看到我在说什么,唯一的区别是我希望红色部分转向相反的方向。

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

我试图仅在有方形装载机的地方显示绿色微调器。它就像一个面具。在上面的 sn-p 中(也可以在这里找到:http://codepen.io/anon/pen/ZOoByA),我正在尝试使用 clip-path 属性。 有人能告诉我为什么clip-path: url(#myClip); 不起作用吗?当我评论这一行时,加载程序完全显示,但是在活动时它根本不显示。

【问题讨论】:

    标签: css css-animations clip-path


    【解决方案1】:

    您可以使用一些多边形在 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;
    }
    

    结果小提琴:https://jsfiddle.net/apLepsv3/10/

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

    【讨论】:

    • 真棒@Felix,谢谢你帮我解决这个问题!
    【解决方案2】:

    您可以使用 HTML 和 CSS 创建微调器,然后结合使用 clip-path 属性和 svg &lt;clipPath&gt; 元素来消除溢出。

    您的微调器的 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 &lt;polygon&gt; 把它剪掉。

    <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 &lt;clipPath&gt; 元素的 clip-path 属性:

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

    小提琴:https://jsfiddle.net/apLepsv3/2/

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

    【讨论】:

    • 嘿,我尝试了相同的技术,它在您的计算机上是否有效。在我的身上,我没有被 svg 多边形删除的绿色溢出:s31.postimg.org/xerqu3j5n/image.png
    • 啊,浏览器支持。 html 元素上的剪辑路径仅适用于 Firefox。看到这个帖子:stackoverflow.com/questions/19227849/…使用圆形装载机怎么样? jsfiddle.net/vw938pgt
    • 哦!我认为这就是为什么我的测试不起作用的原因,我在 Chrome 上,从未尝试在 Firefox 上测试它......谢谢!你帮了我很多@Felix。
    • 已经有一段时间了...我有一个问题,为什么 this 使用 chrome 而不是我的预加载器?
    • 显然,clip-path 在图像(但不是 div)上使用时适用于 chrome,可能是因为它们很容易转换为 svg 图像。您可以通过使用 svg 路径而不是 html div 来避免浏览器支持(请参阅我的下一个答案)。
    【解决方案3】:

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

    <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/

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

    【讨论】:

    • 感谢您的回答,但是当我说在里面时,我的意思是实际上在方形装载机的灰色部分内......你有什么想法吗?
    • 抱歉,我想的更像是绿色部分会在广场内流动
    • 再次更新;现在它按预期工作(我希望),但您需要更多元素。
    • 非常感谢!是的,它有效,我没有想到使用溢出:隐藏。我失去了希望,尽我所能使用剪辑路径......“其他元素”是什么?
    • @Ivan,因为这是一个完全不同的解决方案,我发布了一个新答案。
    猜你喜欢
    • 2017-07-04
    • 2012-02-14
    • 2022-01-13
    • 2021-05-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多