3

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

关键帧动画可以做到这一点吗?我已经看到它使用转换属性完成,但没有使用 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/ *如果您在动画完成之前单击“游戏”圆圈,您会注意到其他两个跳转到 100% 然后动画出来(就是这样我正在努力使平滑)。

我什至尝试从 Bounce-Out 中删除 0% 关键帧,但这并没有帮助......

4

1 回答 1

12

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

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


简单的方法

您可以通过 '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,所以你可以看到它工作。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";


等等瞧。我在这里做了一个jsfiddle,所以你可以玩它。


更多的糖

  • 在您的示例中,圆圈以交替方式弹跳出弹跳。通过对所有运动圈动画使用 setTimeout,您可以轻松地将其恢复为使用第二个解决方案。我不想在这里包含它,因为它会使示例代码不必要地复杂化。

  • 我知道所提供的示例并不是真正的 DRY,例如,您可以使用一半的代码行(具有元属性)使所有事件和运动的东西都工作,但就可读性而言,我认为这个示例很好用。

  • 要让这个示例在所有支持 css3 动画的浏览器中工作,您需要规范化过渡属性。要在 javascript 中执行此操作,请查看此处示例也适用于动画和其他属性,只需将 'transition' 替换为您想要的属性

  • 为了进一步了解动态修改 css3 动画,我发现这篇文章非常有用,也可以看看它。

于 2012-07-10T07:58:53.430 回答