我使用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按钮,仅用于演示目的。真正的问题是由快速的用户交互触发的,应该立即得到反馈。
答案 0 :(得分:2)
检查这是否对您有所帮助。
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');
}
}
答案 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;
}