主题
缓动效果
用处
对几乎所有类型的过渡动画来说,它都可以显著增强动画的体验
- 尺寸变化,如 :hover 时变大,弹出框弹出时等
- 角度变化,如元素的旋转动作,饼图从 0 过渡到实际大小等
弹跳动画
第一想法是使用 CSS 动画
css
@keyframes bounce {
60%, 80%, to { transform: translateY(200px); }
70% { transform: translateY(100px) }
90% { transform: translateY(130px) }
}
.box {
animation: bounce 3s;
}
但如动画一样,效果并不好,这是因为动画的调速与弹跳运动的加速度不一致,下面是各个调速函数 animation-timing-function
(默认值是 ease
)
按物理认知,在下降过程中,加速度是逐渐增加的(ease-in
);在上升过程中,加速度是逐渐减少的(ease-out
)
css
@keyframes bounce {
60%, 80%, to {
transform: translateY(200px);
animation-timing-function: ease-out;
}
70% { transform: translateY(100px) }
90% { transform: translateY(130px) }
}
.box {
animation: bounce 3s ease-in;
}
效果好了很多,但还没达到完美,所以我们需要使用自定义调速函数,cubic-bezier(x1, y1, x2, y2)
,如下图,紫粉色的是 (x1, y1),青蓝色的是 (x2, y2)。但调到想要的函数比较困难,可以通过下面网站调节
css
/* 这里使用 animate.css 库的函数,效果会好很多 */
@keyframes bounce {
60%, 80%, to {
transform: translateY(200px);
animation-timing-function: cubic-bezier(.215,.61,.355,1);
}
70% { transform: translateY(100px) }
90% { transform: translateY(130px) }
}
.box {
animation: bounce 3s cubic-bezier(.755,.05,.855,.06);
}
弹性过渡
初始效果:文本输入框被聚焦时,弹出一个提示框
html
<label>
用户名:
<input type="text">
<span>用户名已存在</span>
</label>
css
input:not(:focus) + span {
transform: scale(0);
}
label span {
transition: transform .3s;
transform-origin: 10px -7px;
}
如何使动画更生动?比如说,先扩大到 110%,再缩回 100%,当然可以把过渡改成动画,但是否有更简单的方法呢?
css
/* 把过渡改成动画 */
@keyframes elastic {
from { transform: scale(0); }
70% { transform: scale(1.1); }
}
其实 cubic-bezier()
就可以做到,正常来说描点应该是再 [0, 1],x 轴上确时只能在这个区间变化,但 y 轴却是可以突破这个区间
的,从而使其经历一个比最终值更大的状态
但注意,收缩回去的时候,同样会过度,出现如下的情况,所以应该这样写
css
input:not(:focus) + span {
transform: scale(0);
transition-timing-function: ease; /* 回缩时用正常的调速函数 */
}
label span {
transition: transform .3s cubic-bezier(.25,.1,.3,1.5);
transform-origin: 10px -7px;
}