动画SVG的动画沿路径长度线性填充

时间:2018-04-21 15:24:10

标签: css animation svg

我有一个代表瘦身的SVG文件。我想制作一个动画,以便整个形状出现。

我正在谈论的' S'三星Galaxy S品牌的标志: https://codepen.io/anon/pen/MGawzy

动画代码(因为StackOverflow强迫我包含它):

@keyframes test {
  0% {
    clip-path: inset(0px 0px 300px 0px);
  }
  80% {
    clip-path: inset(0px 0px 0px 0px);
  }
  100% {
    clip-path: inset(0px 0px 0px 0px);
  }
}

svg {
  animation: test;
  animation-duration: 2s;
  animation-timing-function: linear;
  animation-iteration-count: infinite;
}

上例中的一个简单的SVG很容易制作动画,我可以从上到下慢慢地取消SVG裁剪。但如果我有一个非常复杂的形状,不能以这种方式动画(也许是美国宇航局的红线标志:https://upload.wikimedia.org/wikipedia/commons/e/e5/NASA_logo.svg),我需要一个更好的解决方案。

再次澄清,我不想动画中风。我希望能够为填充设置动画,就像它已经开始绘制一样。

这有什么一般解决方案吗?如果没有通用的解决方案,我将如何在合理的时间内自行设置关键帧?

编辑:为了提供一些见解,我试图为高音谱号设置动画:https://upload.wikimedia.org/wikipedia/commons/e/e8/G-clef.svg

2 个答案:

答案 0 :(得分:10)

你可以做到这一点(更容易描述而不是做,有很多繁琐的工作):

  1. 在形状顶部绘制一条平滑的路径,该路径遵循您认为的"路径"并选择这样一个行程宽度,使路径到处覆盖形状。
  2. 我会把最后一个点完全排除在外,因为它比其他部分厚得多。
  3. 以不具有重叠部分的方式划分路径。按照绘图顺序对零件进行排序,确保每个部分路径都以正确的方向绘制。
  4. 现在以相同的方式划分形状,确保每个部分正好位于顶部的路径下方。
  5. 将每个形状与顶部的一个路径相关联,将路径定义为形状的遮罩。路径必须为stroke:white。保留订单。
  6. 现在,您可以使用stroke-dashoffset animation
  7. 为定义蒙版的路径设置动画
  8. 我会隐藏最后一个点,直到伪线动画结束,然后立即显示它。
  9. 编辑:我今天肯定有太多时间在手上,这是工作结果:

    
    
    .clef {
        fill: black;
        stroke: black;
        stroke-width: 0.1;
    }
    mask path {
        fill: none;
        stroke: white;
        stroke-width: 6;
    }
    #mask1 path {
        stroke-dasharray: 100.8186 100.8186;
        stroke-dashoffset: 100.8186;
        animation: draw1 1s linear forwards;
    }
    @keyframes draw1 {
        from { stroke-dashoffset: 100.8186; }
        to { stroke-dashoffset: 0; }
    }
    #mask2 path {
        stroke-dasharray: 83.6713 83.6713;
        stroke-dashoffset: 83.6713;
        animation: draw2 1s 1s linear forwards;
    }
    @keyframes draw2 {
        from { stroke-dashoffset: 83.6713; }
        to { stroke-dashoffset: 0; }
    }
    .dot {
        opacity: 0;
        animation: reveal 0s 2.5s forwards;
    }
    @keyframes reveal {
        from { opacity: 0; }
        to { opacity: 1; }
    }
    
    <svg xmlns="http://www.w3.org/2000/svg" width="100" height="200" viewBox="0 0 44 75">
      <defs>
      <mask id="mask1" maskUnits="userSpaceOnUse">
          <path d="M 24.3018,49.658 C 15.0191,46.9092 18.5393,38.1126 25.6256,38.2163 35.5458,38.3614 34.8431,54.3874 22.6943,54.1023 12.0123,53.8516 7.34095,40.0402 18.4391,30.1787 29.5373,20.3173 29.9235,12.5622 27.8005,9.28112" />
      </mask>
      <mask id="mask2" maskUnits="userSpaceOnUse">
          <path d="M 27.8005,9.28112 C 25.1382,5.16638 17.6602,8.86888 20.5194,22.1412 L 28.1788,57.6956 C 31.6264,73.699 16.4903,72.3627 15.035,62.329" />
      </mask>
      </defs>
      <path class="clef" mask="url(#mask1)" d="M 26.8522,9.90048 C 26.912,9.95039 26.9649,10.0085 27.0101,10.075 27.4815,10.7683 28.6214,14.0098 25.3767,19.8157 22.846,24.3437 11.0718,30.2815 10.2077,40.9075 9.45969,50.1477 19.1325,56.9723 27.4811,54.2894 33.0239,52.5081 35.8812,44.0959 32.4504,39.7568 23.3964,28.3057 8.87616,45.8309 22.9422,50.6319 21.4126,49.4286 20.37,48.4968 20.1759,47.3578 18.286,36.2692 34.9591,39.1968 30.4666,49.7165 28.6194,54.0421 21.1577,54.879 16.9085,51.0198 13.3489,47.787 11.7693,41.5593 15.7305,37.0885 21.0956,31.0332 27.4302,25.5974 29.1125,17.3081 29.7841,13.9988 29.4887,10.9357 28.6445,8.70078 Z" />
      <path class="clef" mask="url(#mask2)" d="M 15.7311,63.3465 C 15.3353,65.46 17.5402,69.8491 21.9764,69.9924 27.3392,70.1658 30.7655,66.0634 29.1692,59.3682 L 21.164,22.4229 C 20.2111,18.0249 20.9262,15.6394 21.4351,14.2178 22.7185,10.6326 25.8192,9.03863 26.8522,9.90048 L 28.6445,8.70078 C 26.9883,4.31578 23.2199,3.11893 20.4997,9.50576 19.1217,12.7412 18.6085,15.989 19.9279,22.2128 L 27.9268,59.9444 C 28.4995,62.6457 28.1161,66.3629 25.595,68.0714 24.3461,68.9177 19.9267,69.5001 18.8455,67.48" />
      <path class="clef dot" d="M 15.6702,63.6634 A 3.77139,3.8362 1.075 0 1 19.5129,59.8986 3.77139,3.8362 1.075 0 1 23.2116,63.8049 3.77139,3.8362 1.075 0 1 19.3689,67.5697 3.77139,3.8362 1.075 0 1 15.6702,63.6634 Z" />
    </svg>
    &#13;
    &#13;
    &#13;

答案 1 :(得分:6)

SVG解决方案

在此示例中,使用了来自@ccprog响应的解决方案,但动画从CSS规则直接移动到SVG动画命令

实现动画的命令对于所有补丁都是相同的。每个补丁的stroke-dasharraystroke-dashoffset属性的数值差异:

<animate attributeName="stroke-dashoffset" dur="1s" values="100.8186;0" fill="freeze" />

在高音谱号末尾出现点的动画命令:

<animate attributeName="opacity" dur="0.05s" values="0;1" begin="an2.end-0.05s" fill="freeze" />

<svg xmlns="http://www.w3.org/2000/svg" width="100" height="200" viewBox="0 0 44 75">
  <defs>
    <mask id="mask1" maskUnits="userSpaceOnUse">
      <path fill="none" stroke="white" stroke-width="6" stroke-dasharray="100.8186" stroke-dashoffset="100.8186" d="M 24.3018,49.658 C 15.0191,46.9092 18.5393,38.1126 25.6256,38.2163 35.5458,38.3614 34.8431,54.3874 22.6943,54.1023 12.0123,53.8516 7.34095,40.0402 18.4391,30.1787 29.5373,20.3173 29.9235,12.5622 27.8005,9.28112">
        <animate attributeName="stroke-dashoffset" dur="1s" values="100.8186;0" fill="freeze"/>
      </path>
    </mask>
    <mask id="mask2" maskUnits="userSpaceOnUse">
      <path fill="none" stroke="white" stroke-width="6" stroke-dasharray="83.6713" stroke-dashoffset="83.6713" d="M 27.8005,9.28112 C 25.1382,5.16638 17.6602,8.86888 20.5194,22.1412 L 28.1788,57.6956 C 31.6264,73.699 16.4903,72.3627 15.035,62.329" >
        <animate id="an2" attributeName="stroke-dashoffset" dur="1s" values="83.6713;0" begin="+1s" fill="freeze"/>
      </path>
    </mask>
  </defs>
  <path class="clef" fill="black" stroke="black" stroke-width="0.1" mask="url(#mask1)" d="M 26.8522,9.90048 C 26.912,9.95039 26.9649,10.0085 27.0101,10.075 27.4815,10.7683 28.6214,14.0098 25.3767,19.8157 22.846,24.3437 11.0718,30.2815 10.2077,40.9075 9.45969,50.1477 19.1325,56.9723 27.4811,54.2894 33.0239,52.5081 35.8812,44.0959 32.4504,39.7568 23.3964,28.3057 8.87616,45.8309 22.9422,50.6319 21.4126,49.4286 20.37,48.4968 20.1759,47.3578 18.286,36.2692 34.9591,39.1968 30.4666,49.7165 28.6194,54.0421 21.1577,54.879 16.9085,51.0198 13.3489,47.787 11.7693,41.5593 15.7305,37.0885 21.0956,31.0332 27.4302,25.5974 29.1125,17.3081 29.7841,13.9988 29.4887,10.9357 28.6445,8.70078 Z"/>
  <path class="clef" fill="black" stroke="black" stroke-width="0.1" mask="url(#mask2)" d="M 15.7311,63.3465 C 15.3353,65.46 17.5402,69.8491 21.9764,69.9924 27.3392,70.1658 30.7655,66.0634 29.1692,59.3682 L 21.164,22.4229 C 20.2111,18.0249 20.9262,15.6394 21.4351,14.2178 22.7185,10.6326 25.8192,9.03863 26.8522,9.90048 L 28.6445,8.70078 C 26.9883,4.31578 23.2199,3.11893 20.4997,9.50576 19.1217,12.7412 18.6085,15.989 19.9279,22.2128 L 27.9268,59.9444 C 28.4995,62.6457 28.1161,66.3629 25.595,68.0714 24.3461,68.9177 19.9267,69.5001 18.8455,67.48"/>
  <path class="clef dot" opacity="0" d="M 15.6702,63.6634 A 3.77139,3.8362 1.075 0 1 19.5129,59.8986 3.77139,3.8362 1.075 0 1 23.2116,63.8049 3.77139,3.8362 1.075 0 1 19.3689,67.5697 3.77139,3.8362 1.075 0 1 15.6702,63.6634 Z">
    <animate attributeName="opacity" dur="0.05s" values="0;1" begin="an2.end-0.05s" fill="freeze"/>
  </path>
</svg>

更新 SMIL SVG - caniuse

无法使用IE/Edge