首页 > 解决方案 > 技能栏的 SMIL 动画

问题描述

我一直在寻找几个小时和几个小时,我只是不明白我怎么找不到在 SMIL 中为技能栏设置动画的解决方案。

因此,我有一个由两条路径组成的 SVG,一条用于外边框,另一条用于填充,我想将页面的填充加载动画从 0 开始并在给定数量后达到其最终宽度或位置时间(比如 800 毫秒)。看看 HTML: https ://codepen.io/anon/pen/PaOqrr

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="80%" viewBox="0.626 346.31 226.762 13.796" enable-background="new 0.626 346.31 226.762 13.796" xml:space="preserve">
<path fill="#4A929D" d="M159.155,353.208c0,3.536-2.868,6.398-6.398,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0 c0-3.531,2.865-6.397,6.397-6.397h145.233C156.289,346.81,159.155,349.676,159.155,353.208L159.155,353.208z"/>
<path fill="none" stroke="#88C2C8" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="0,2" d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>

我真的只想通过 SMIL 来实现这一点。我知道如何使用 JS 和 CSS,但我不敢相信这不适用于 animate。

我已经尝试过属性“x”和“width”,但它没有让步。

任何想法?

标签: svgjquery-animatesmil

解决方案


路径没有xorwidth属性,因此为它们设置动画不会做任何事情。

有几种方法可以实现您想要的。但最简单的可能是使用蒙版或剪辑路径来定义点之间的区域,然后为进度条的位置设置动画。您将从左侧开始(即通过剪辑不可见),然后慢慢将其向右移动,以使其看起来越来越长。

您当前的进度条仅涵盖了我们大约三分之二的进度。所以我们不能真正使用它。缩放或移动它对我们没有帮助。所以我们不妨丢弃它。

但是我们可以使用点路径,因为它符合我们的需要。如果我们复制路径定义,我们会得到以下信息:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
         width="80%" viewBox="0.626 346.31 226.762 13.796">
  <path fill="#4A929D"
        d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>
  <path fill="none" stroke="#88C2C8" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="0,2"
        d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>
</svg>

我们现在可以通过为该路径设置动画来为进度条设置动画transform。我们使用translate()变换将其从左向右移动适当的量。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
         width="80%" viewBox="0.626 346.31 226.762 13.796">
  <path fill="#4A929D"
        d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z">
    <animateTransform attributeName="transform" attributeType="XML"
                      type="translate" from="-226, 0" to="0, 0"
                      dur="3s" fill="freeze"/>
  </path>
  <path fill="none" stroke="#88C2C8" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="0,2"
        d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>
</svg>

现在单独移动它是不够的。我们需要隐藏移动条在我们的点通道之外的部分。我们可以通过应用 a<mask>或 a来做到这一点<clipPath>。我将使用剪辑路径。由于剪辑路径将与进度条路径和点路径具有相同的形状,因此我们将使用相同的定义。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
         width="80%" viewBox="0.626 346.31 226.762 13.796">
  <defs>
    <clipPath id="bar-clip">
      <path d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>
    </clipPath>
  </defs>
  <g clip-path="url(#bar-clip)">
    <path fill="#4A929D"
          d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z">
      <animateTransform attributeName="transform" attributeType="XML"
                        type="translate" from="-226, 0" to="0, 0"
                        dur="3s" fill="freeze"/>
    </path>
  </g>
  <path fill="none" stroke="#88C2C8" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="0,2"
        d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>
</svg>

当您查看上述内容时,您可能想知道为什么我们将剪辑应用于组 ( <g>) 而不是直接应用于进度条路径本身。原因是,如果我们将它应用到路径上,它会受到动画变换的影响。它将随路径移动,因此不会发生剪切。

最后,我们在这里使用相同的路径三​​次。您可能想知道我们是否可以做任何事情来使文件更小。答案是肯定的。我们可以只定义一次路径,然后在需要的任何地方引用它。我们可以通过使用<use>元素来做到这一点。

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
         width="80%" viewBox="0.626 346.31 226.762 13.796">
  <defs>
    <clipPath id="bar-clip">
      <path id="bar-shape" d="M226.888,353.208 c0,3.536-2.867,6.398-6.397,6.398H7.524c-3.533,0-6.397-2.864-6.397-6.398l0,0c0-3.531,2.865-6.397,6.397-6.397H220.49 C224.021,346.81,226.888,349.676,226.888,353.208L226.888,353.208z"/>
    </clipPath>
  </defs>
  <g clip-path="url(#bar-clip)">
    <use xlink:href="#bar-shape" fill="#4A929D">
      <animateTransform attributeName="transform" attributeType="XML"
                        type="translate" from="-226, 0" to="0, 0"
                        dur="3s" fill="freeze"/>
    </use>
  </g>
  <use xlink:href="#bar-shape" fill="none" stroke="#88C2C8" stroke-linecap="round" stroke-miterlimit="10" stroke-dasharray="0,2"/>
</svg>


推荐阅读