动画SVG沿路径长度线性填充 [英] Animating SVG fill linearly along length of path

查看:86
本文介绍了动画SVG沿路径长度线性填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表示薄形的SVG文件。我想制作一个动画,使整个形状看起来被绘制出来。

I have an SVG file that represents a thin shape. I would like to craft an animation such that the entire shape appears be being drawn out.

三星Galaxy S品牌的S'徽标:
https://codepen.io/anon/ pen / MGawzy

Example of what I am talking about with the 'S' logo from the Samsung Galaxy S brand: https://codepen.io/anon/pen/MGawzy

动画代码(因为StackOverflow迫使我将其包括在内)

Animation code (because StackOverflow forces me to include it):

@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。但是,如果我的形状非常复杂,无法以这种方式进行动画处理(也许是NASA徽标中的红线: https://upload.wikimedia.org/wikipedia/commons/e/e5/NASA_logo.svg ),我需要一个更好的解决方案。

A simple SVG in the example above is easy to animate, I can just slowly un-crop the SVG from top-down. But if I have a very complex shape which cannot be animated in this manner (maybe the red line in NASA's logo: https://upload.wikimedia.org/wikipedia/commons/e/e5/NASA_logo.svg), I need a better solution.

请再次说明一下,我不想为笔划设置动画。我希望能够对填充进行动画处理,就像开始绘制一样。

对此是否有任何一般的解决方案?如果没有通用的解决方案,我该如何在合理的时间内自行对密钥进行构架?

Is there any general solution to this? If there is no general solution, how would I go about key-framing this on my own in a reasonable amount of time?

编辑:为了提供一些见识,我正在尝试制作高音谱号的动画: https://upload.wikimedia.org/wikipedia/commons/e/e8/G-clef.svg

To give some insight, I'm trying to animate the treble clef: https://upload.wikimedia.org/wikipedia/commons/e/e8/G-clef.svg

推荐答案

您可以执行此操作(比做起来容易描述,涉及很多繁琐的工作):

You could do this (easier to describe than to do, there's a lot of fiddly work involved):


  1. 画一条流畅的路在遵循您认为的路径的形状的顶部,并选择这样的笔划宽度,以使该路径覆盖所有位置的形状。

  2. 我将最后一个点完全排除在外

  3. 以这样的方式划分路径,使其没有重叠的部分。按图纸顺序排列零件,确保每个局部路径都沿正确的方向绘制。

  4. 现在以相同的方式划分形状,确保每个零件都位于顶部路径的正下方。

  5. 将每个形状与顶部的路径之一相关联,将路径定义为形状的遮罩。该路径必须具有 stroke:white 。保留顺序。

  6. 现在,您可以使用 笔划距偏移量动画

  7. 我只会隐藏最后一个点,直到伪行动画结束后立即显示。

  1. Draw a smooth path on top of the shape that follows what you would consider the "path" and select such a stroke-width that the path covers the shape everywhere.
  2. I would leave the final dot completely out of this, as it is so much thicker than the rest.
  3. Divide the path in such a way that it has no overlapping parts. Order the parts in drawing order, make sure every partial path is drawn in the right direction.
  4. Now divide the shape in the same way, making sure each part is exactly beneath the path on top.
  5. Associate each of the shapes with one of the paths on top, defining the path as a mask for the shape. The path must have stroke:white. Preserve order.
  6. Now you can animate the paths that define the masks with a stroke-dashoffset animation.
  7. I would simply hide the final dot until the pseudo-line animation finishes and then reveal it at once.

编辑:我肯定有太多时间今天是我的工作结果:

I've definitely got too much time on my hands today, here's the working result:

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

这篇关于动画SVG沿路径长度线性填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆