【问题标题】:Snap.svg animation run multiple times ends with different valuesSnap.svg 动画多次运行以不同的值结束
【发布时间】:2018-03-29 01:03:11
【问题描述】:

我有一个圈子。我想创建一个函数,将其从 1 比例设置为 0.8 并返回到 1。我目前的工作是有效的,但是当我连续多次调用它并且几乎没有延迟时,动画会发生冲突,并且圆圈会以不同的方式结束(较小的)规模。

在进行所有缩放操作时,我希望圆圈保持在其位置。另外,我希望使用圆中心的锚点进行缩放。目前就是这种情况。

看看this fiddle

由于以上原因,我得到了圆的当前变换:

var trans = elem.attr("transform");

重置它的比例:

trans.totalMatrix.scale(1);

并应用它:

elem.attr({transform: trans});

然后,我将animate() 调整到所需的比例(在本例中为0.8),如下所示:

transform: "s" + scale + "," + scale + trans

完成后,我animate() 回到原来的变换,缩放比例为1

transform: trans

动画运行几次后,圆圈以较小的比例结束。 为什么?

编辑:

动画之间的延迟有意小于动画本身的长度。我的问题是如何使动画工作尽管

【问题讨论】:

    标签: javascript animation svg snap.svg


    【解决方案1】:

    您的主要问题是setInterval() 中的值太短。您在动画完成之前重新启动它。

    如果您不尝试合并两个转换,您也可以稍微简化一切。将translate() 移到父组,事情就干净了一些。

    var snapelem = Snap("svg");
    circ = snapelem.select("#mycirc");
    
    var bounce = function (elem, scale, duration) {
    
        elem.animate({
            transform: "s" + scale + "," + scale
        }, duration * 0.33, mina.easeout, function () {
            elem.animate({
                transform: "s1,1"
            }, duration * 0.67, mina.easein);
        });
    };
    
    var count = 0;
    setInterval(function () {
        if (++count > 10) return;
        bounce(circ, 0.8, 500);
    }, 500);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/snap.svg/0.5.1/snap.svg-min.js"></script>
    
    <svg height="300px" width="500px">
      <g transform="translate(40 40)">
        <circle id="mycirc" cx="50" cy="50" r="40" stroke="black" stroke-width="3" fill="red" />
      </g>
    </svg>

    【讨论】:

    • 我知道我要在动画完成之前重新启动它。我在问我如何才能让它发挥作用。无论何时播放,我都希望它始终以 1 的比例结束。
    • 如果您使用我的代码并将 setInterval 值改回 200,您会看到它以 1 结束。
    • 嗯,没注意到。但是,我使用的实时 SVG 无法更改,因此转换 必须&lt;circle&gt; 上是否有办法让它以这种方式工作并且 仍然最终达到规模1? IE。如何在保留初始转换的同时使其工作?
    • 抱歉,我不太了解 Snap,无法轻松回答这个问题。
    【解决方案2】:

    我像这样更改了反弹和 setInterval 函数,效果很好。 setInterval 时间必须大于 500ms(我用的是 550ms),并且在 animate 函数的回调中你不应该再次使用 scale(0.8),你必须将它返回到它的默认比例,即 1:

    var bounce = function (elem, scale, duration) {
        var trans = elem.attr("transform");
        trans.totalMatrix.scale(1);
    
        elem.attr({
            transform: trans
        });
    
        elem.animate({
            transform: "s" + scale + "," + scale + trans
        }, duration * 0.33, mina.easeout, function () {
            elem.animate({
                transform: "s" + 1 + "," + 1 + trans // I changed the scale to 1
            }, duration * 0.67, mina.easein);
        });
    };
    
    var count = 0;
    setInterval(function () {
        if (++count > 10) return;
        bounce(circ, .8, 500);
    }, 550); // I canged this to 550
    

    【讨论】:

      【解决方案3】:

      您需要存储初始转换,否则在同一个对象上有多个动画时,它们会混淆(无论如何它们都会混淆)。因此,首先,您需要确保动画不重叠。我从其他 cmets 看到,这是示例的一部分,所以暂时将其放在一边,但请确保在实时代码中不会发生这种情况:)。

      所以你可以存储转换

      var trans = circ.attr("transform");
      

      然后将其传递给func

      bounce(circ, 0.8, 500, trans);
      

      在函数中,使用那个...

      var bounce = function (elem, scale, duration, trans) {
      ....
      

      jsfiddle

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-08-23
        • 2020-06-26
        • 2021-11-19
        • 2013-12-15
        相关资源
        最近更新 更多