CSS 揭秘(8)--状态平滑的动画

Posted by liveipool on February 9, 2017

状态平滑的动画

  • 不是所有动画都是在页面一加载好就立即播放的。更常见的情况是,我们想通过动画来响应用户的动作,比如用户的鼠标悬停在某个元素上( :hover ),或者按住鼠标键( :active ),等等。在这种场景下,我们将无法控制动画实际的循环次数,因为用户的动作会随时中断动画,而此时动画不可能刚好插放到我们事先指定的循环次数。
  • 举例来说,用户的鼠标可能会触发一个华丽的 :hover 动画,而在动画还没有播完的时候,鼠标就从元素上移走了。在这种情况下,你觉得动画会如何收场呢?
  • 如果觉得“动画应该停留在当前状态”或者“动画应该平滑地过渡回开始状态” ,那你就要大跌眼镜了。在默认情况下,动画只会立即停止播放,并生硬地跳回开始状态。(这也是我们尽可能的采用过渡的另一个原因,此时动画会生硬地跳回开始状态,但过渡的行为完全不同,过渡会反向播放,从而平稳地过渡回原始状态。)对于某些非常细微的动画来说,这种行为还算可以接受。但在绝大多数时候,这只会产生非常生硬的用户体验。我们有可能改变这种行为吗?

假设我们有一张较长的图片却只有300×300的空间来展示它。为了突破这种窘境,我们想到了动画的方法:在默认情况下只显示这张照片的左边缘,当用户和他交互时,让它滚动显露出剩余的部分。
下面具体操作一下:

div {
	width: 300px;
	height: 300px;
	background: url("/static/pictures/08685344-11d9-426d-a204-ccabbf7049ba-2060x1236.jpeg");
	background-size: auto 100%;
}

46.1.png
接下来我们可能会想加上hover交互:

div {
	width: 300px;
	height: 300px;
	background: url("/static/pictures/08685344-11d9-426d-a204-ccabbf7049ba-2060x1236.jpeg");
	background-size: auto 100%;
}

@keyframes panoramic {
	to {background-position: 100% 0;}
}

div:hover, div:focus {
	animation: panoramic 5s linear infinite alternate;
}

但是现在最常见的问题来了,当我们把鼠标移除图片时,动画就会最生硬的直接跳回原样。

然而,仔细想想,其实我们需要的并不是在:hover时应用一个动画,因为这意味着动画被中断时的状态是无法保存的。我们需要的是当失去:hover状态时暂停动画!!
因此,我们应该使用animation-play-state。

div {
	width: 300px;
	height: 300px;
	background: url("/static/pictures/08685344-11d9-426d-a204-ccabbf7049ba-2060x1236.jpeg");
	background-size: auto 100%;
	animation: panoramic 5s linear infinite alternate;
	animation-play-state: paused;
}

@keyframes panoramic {
	to {background-position: 100% 0;}
}

div:hover, div:focus {
	animation-play-state: running;
}

这样就优雅的解决了这个问题,以后只是暂停和继续一个一直存在的动画,因此再也不会有生硬的跳回现象了!