CSS3过渡中止导致丑陋的动画

时间:2015-01-06 04:22:01

标签: css css3

我使用CSS3步骤转换将精灵从一个状态设置为另一个状态。

当我开始一个动画时,它一次显示一个帧并具有很好的过渡效果(单击"显示/隐藏" example中的链接)。但是当第一个转换被触发而第一个转换仍在运行时,帧位置会丢失并且它看起来像是滚动到另一侧而不是保持逐帧动画(单击"触发错误"在example)。

.tree {
    width: 26px; /* one frame */
    height: 31px; /* frame height */
    background-image: url("http://rolandschuetz.at/docs/tree-animated.png");
    background-repeat: no-repeat;
    background-position: -234px 0; /* last frame */
    transition: background-position .8s steps(10); /* this triggers the CSS3 step transition */
}
.tree-hidden {
    background-position: 26px 0; /* clear, before first frame */
}

有没有办法强制动画即使在中止旧动画时也能正常工作?

PS:请不要试图"修复"通过trigger-bug按钮,仅用于演示目的。真正的问题是由快速的用户交互触发的,应该立即得到反馈。

4 个答案:

答案 0 :(得分:2)

Updated code

检查这是否对您有所帮助。

HTML

<div class="outer"> <!--Added this div-->
  <div class="tree"></div>        
</div>

CSS:

.outer {
    width: 26px;
    border: 1px solid grey;
}
.tree {
    width: 26px; /* one frame */
    height: 31px;

    background-image: url("http://rolandschuetz.at/docs/tree-animated.png");
    background-repeat: no-repeat;
    background-position: -234px 0; /* last frame */
    -webkit-transform: scale(1);
    margin: 0 auto;    
    /*Changed transition*/
    -webkit-transition: all .8s;
       -moz-transition: all .8s;
        -ms-transition: all .8s;
            transition: all .8s;
}
.tree-hidden {
    /* background-position: 26px 0; */ /* empty, before first frame */
    width: 0;
    -webkit-transform: scale(0);
}

答案 1 :(得分:2)

问题在于:

有10个帧,因此您使用10个步骤进行动画制作。 所以基本上,CSS为树活动而踩树10次,而树活跃10次。

如果在第8帧取消激活树,它将按预期反转动画方向,但它会步进10次而不是8次。这使得它看起来像是在滑动,但它实际上只是在10个间隔位置停止对于8帧。

这有意义吗?

对于这种类型的动画,你最好使用JS解决方案,它知道当前的帧位置并正确计算所需的步骤。

我希望这有帮助!

答案 2 :(得分:2)

正如ThePav所说,没有办法让CSS知道它的状态。所以,它总是一个step(10)函数,即使从上一个转换的中间开始,并且背景位置需要较少的步骤。

解决此问题的最简单方法(不容易,但最简单)是设置并行z-index转换,设置方法与背景位置相同。如果你可以给它们任何z-index,那么z-index将从0到10。

.tree {
    background-position: -234px 0; 
    z-index: 0;
    transition: all .8s steps(10); // will apply both to bkg-position and z-index
}
.tree-hidden {
    background-position: 26px 0; 
    z-index: 10;
}

然后,z-index属性用作正在进行的转换的指示器,您可以在脚本中相应地设置步骤功能以更改类。

即获取z-index的值,并将其设置为transitionTimingFunction:'steps('+ zindexval +')'

(您也可以使用background-position属性执行此操作,但这样做更难。)

代码是

function change () {
    var tree = $('.tree').eq(0);
    if (tree.hasClass('tree-hidden')) {
        var where = tree.css("zIndex");
        if (where != 10) {
            tree.css({transitionTimingFunction: 'steps(' + where + ')'})
        } else {
            tree.css({transitionTimingFunction: ''})
        }
        tree.removeClass('tree-hidden');
    } else {
        tree.css({transitionTimingFunction: ''})
        tree.addClass('tree-hidden');
    }

}

demo

答案 3 :(得分:0)

使用transitionend等待删除&#39; tree-hidden&#39;类。否则你无法通过其他方式解决。

$('.show-hide').click(function() {
    !$('.tree').hasClass('tree-hidden') &&
    $('.tree').addClass('tree-hidden').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
        $('.tree').removeClass('tree-hidden')
    });
});

<强>更新

 $('.show-hide').click(function(evt) {
    //JUST CHECK ALREADY HAS HIDDEN CLASS
    if($('.tree').hasClass('tree-hidden'))
     //you can event prevent defaul if there is no another work
     evt.preventDefault();
     return false;
    $('.tree').addClass('tree-hidden').one('webkitTransitionEnd otransitionend oTransitionEnd msTransitionEnd transitionend', function(e) {
        $('.tree').removeClass('tree-hidden')
    });
});     

通过这种方式,无论点击更多时间,交易都不会在动画完成之前中断。

css交易回退

如果您需要后备,可以使用以下代码

function supportsTransitions() {
   var b = document.body || document.documentElement,
    s = b.style,
    p = 'transition';

    if (typeof s[p] == 'string') { return true; }

    // Tests for vendor specific prop
    var v = ['Moz', 'webkit', 'Webkit', 'Khtml', 'O', 'ms'];
    p = p.charAt(0).toUpperCase() + p.substr(1);

    for (var i=0; i<v.length; i++) {
        if (typeof s[v[i] + p] == 'string') { return true; }
    }

    return false;
}