首页 文章

CSS3动态更改动画时的平滑过渡

提问于
浏览
3

我有两个关键帧动画“Bounce-In”和“Bounce-Out”Bounce-In动画需要1.2秒才能完成,但是如果用户在完成之前触发Bounce-Out功能,它将跳到100%的比例并且不会优雅地从它的当前动画位置向外扩展 .

关键帧动画可以实现吗?我已经看到它完成了转换属性但没有使用scale() .

@-webkit-keyframes Bounce-In 
{
0% { -webkit-transform: scale(0) }
40% { -webkit-transform: scale(1.0) }
60% { -webkit-transform: scale(0.7) }
80% { -webkit-transform: scale(1.0) }
90% { -webkit-transform: scale(0.9) }
100% { -webkit-transform: scale(1.0) }
}

@-webkit-keyframes Bounce-Out 
{
0% { -webkit-transform: scale(1.0) }
40% { -webkit-transform: scale(0.1) }
60% { -webkit-transform: scale(0.4) }
80% { -webkit-transform: scale(0.1) }
90% { -webkit-transform: scale(0.2) }
100% { -webkit-transform: scale(0) }
}

我在JSFiddle上有一个演示:http://jsfiddle.net/Vn3bM/98/ *如果你在动画结束前单击"Games"圈,你会注意到另外两个跳到100%,然后动画出来(那个's what I' m试图平滑) .

我甚至尝试从Bounce-Out中移除0%关键帧,这没有帮助......

1 回答

  • 12

    在您的情况下,您在动画中注意到的“跳跃”来自您在onmouseup上安装的动画的更改 . “Bounce-Out”动画的初始比例为1(第一个Keyframe),这就是安装动画时两个圆圈立即设置的位置 .

    有两种解决方案,我可以详细解释一下:

    简单的方法

    您可以等待初始动画通过'webkitAnimationEnd'事件结束,并使用递归函数安装onmouseup事件,等待动画完成:

    var initAnimationEnded = false;
    document.getElementById('sports').addEventListener('webkitAnimationEnd', function() {
     initAnimationEnded = true;
    }, false);​
    

    这是onmouseup处理程序:

    document.getElementById('games').onmouseup = function() {
      function bounceOut() {
        if (initAnimationEnded) {
            events.style.webkitAnimationName = "Bounce-Out";
            sports.style.webkitAnimationDelay = "0.2s";
            sports.style.webkitAnimationName = "Bounce-Out";
        } else {
            setTimeout(bounceOut, 20);
        }
      }
      bounceOut();
    }
    

    我安装了 jsfiddle here 所以你可以看到它正常工作 . Bounce Out动画仅在动画结束后触发,没有任何异常 .

    艰难的道路

    您可以暂停动画并解析转换的当前值,然后安装临时关键帧动画以退出 . 这会变得更加冗长:

    首先,你必须停止动画:

    events.style.webkitAnimationPlayState = "paused";
    sports.style.webkitAnimationPlayState = "paused";
    

    然后,您设置一个帮助程序来插入新的css规则:

    var addCssRule = function(rule) {
      var style = document.createElement('style');
      style.innerHTML = rule;
      document.head.appendChild(style);
    }
    

    然后即时创建css关键帧规则并插入它们:

    // get the current transform scale of sports and events
    
        function getCurrentScaleValue(elem) {
          return document.defaultView.
          getComputedStyle(elem, null).
          getPropertyValue('-webkit-transform').
          match(/matrix\(([\d.]+)/)[1];
        }
    
        var currentSportsScale = getCurrentScaleValue(sports);
        var currentEventsScale = getCurrentScaleValue(events);
    
         // set up the first string for the keyframes rule
    
        var sportsTempAnimation = ['@-webkit-keyframes Sports-Temp-Bounce-Out {'];
        var eventsTempAnimation = ['@-webkit-keyframes Events-Temp-Bounce-Out {'];
    
         // basic bounce out animation
    
        var bounceOutAnimationBase = {
            '0%': 1,
            '40%': 0.1,
            '60%': 0.4,
            '80%': 0.1,
            '90%': 0.2,
            '100%': 0
        };
    
         // scale the animation to the current values
    
        for (prop in bounceOutAnimationBase) {
            sportsTempAnimation.push([
              prop, ' 
              { -webkit-transform: scale(', 
              currentSportsScale * bounceOutAnimationBase[prop], 
              ') } '].join(''));
            eventsTempAnimation.push([
               prop, 
               ' { -webkit-transform: scale(', 
               currentEventsScale * bounceOutAnimationBase[prop], 
               ') } '
             ].join(''));
        }
    
         // add closing brackets
    
        sportsTempAnimation.push('}');
        eventsTempAnimation.push('}');
    
         // add the animations to the rules
    
        addCssRule([sportsTempAnimation.join(''), 
                    eventsTempAnimation.join('')].join(' '));
    

    然后,使用以下规则重新启动动画:

    events.style.webkitAnimationName = "Events-Temp-Bounce-Out";
        events.style.webkitAnimationDelay = "0s";
        sports.style.webkitAnimationDelay = "0s";
        sports.style.webkitAnimationName = "Sports-Temp-Bounce-Out";
        events.style.webkitAnimationPlayState = "running";
        sports.style.webkitAnimationPlayState = "running";
    

    Etvoilà . 我在这里做了 jsfiddle 所以你可以玩它 .

    更多糖

    • In your example, the circles bounce out alternating in bounce . 通过对所有体育圈动画使用setTimeout,您可以轻松地恢复使用第二个解决方案 . 我不想在这里包含它,因为它会不必要地使示例代码复杂化 .

    • I know the provided examples are not really DRY ,例如,您可以使用一半代码行(使用元属性)使事件和体育的所有内容工作,但就可读性而言,我认为这个示例很好 .

    • To have this example working in all browsers with support for css3 animations ,您需要规范化过渡属性 . 要在javascript中执行此操作,have a look here该示例也适用于动画和其他属性,只需将'transition'替换为您想要的属性

    • For a further read on modifying css3 animations on the fly ,我发现this post非常有用,看看它也是如此 .

相关问题