【发布时间】:2015-08-21 03:04:07
【问题描述】:
我只是使用 CSS 制作一个加载屏幕,我希望它具有物理上准确的行为。我正在尝试使用animation-timing-function: cubic-bezier(1, 0, 1, 1),看起来不错,但不像我想要的那样真实,起初因为我不知道cubic-bezier 参数如何真正起作用,我找到了this 站点并只是玩弄它们直到我得到了一些好东西。
总而言之,我怎样才能在我的动画中添加物理上准确的行为? 我正在寻找一个纯 CSS 的解决方案,但如果不可能的话,JavaScript 也可以。
这里有一个例子:
body{
background-color: #02a2bb;
}
.wrapper {
padding: 50px;
text-align: center;
}
.content {
height: 125px;
margin: 0 auto;
position: relative;
display: inline-block;
}
.ball {
width: 25px;
height: 25px;
display: inline-block;
border-radius: 50%;
bottom: 0;
position: relative;
background-color: #fff;
z-index: 1;
}
.ball-shadow {
width: 20px;
height: 6px;
border-radius: 50%;
position: absolute;
bottom: 9px;
left: 50%;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
transform: translateX(-50%);
}
.animated {
-webkit-animation-duration: 1s;
-moz-animation-duration: 1s;
-ms-animation-duration: 1s;
-o-animation-duration: 1s;
animation-duration: 1s;
-webkit-animation-fill-mode: both;
-moz-animation-fill-mode: both;
-ms-animation-fill-mode: both;
-o-animation-fill-mode: both;
animation-fill-mode: both;
-webkit-animation-iteration-count: infinite;
-moz-animation-iteration-count: infinite;
-ms-animation-iteration-count: infinite;
-o-animation-iteration-count: infinite;
animation-iteration-count: infinite;
}
.animated.jump, .animated.displace, .animated.diffuse-scale {
-webkit-animation-duration: 3s;
-moz-animation-duration: 3s;
-ms-animation-duration: 3s;
-o-animation-duration: 3s;
animation-duration: 3s;
}
@-webkit-keyframes jump {
0% {
opacity: 1;
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: translate(0, 0);
}
15% {
opacity: 1;
-webkit-transform: translate(0, 100px) scale(1.1, 0.9);
}
30% {
opacity: 1;
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: translate(0, 15px);
}
45% {
opacity: 1;
-webkit-transform: translate(0, 100px) scale(1.08, 0.92);
}
60% {
opacity: 1;
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: translate(0, 45px);
}
70% {
opacity: 1;
-webkit-transform: translate(0, 100px) scale(1.05, 0.95);
}
80% {
opacity: 1;
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: translate(0, 65px);
}
85% {
opacity: 1;
-webkit-transform: translate(0, 100px) scale(1.03, 0.97);
}
90% {
opacity: 1;
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: translate(0, 80px);
}
95% {
opacity: 1;
-webkit-transform: translate(0, 100px) scale(1.01, 0.99);
}
97% {
opacity: 1;
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: translate(0, 95px);
}
100% {
opacity: 0;
-webkit-transform: translate(0, 100px);
}
}
@keyframes jump {
0% {
opacity: 1;
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: translate(0, 0);
transform: translate(0, 0);
}
15% {
opacity: 1;
-moz-transform: translate(0, 100px) scale(1.1, 0.9);
transform: translate(0, 100px) scale(1.1, 0.9);
}
30% {
opacity: 1;
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: translate(0, 15px);
transform: translate(0, 15px);
}
45% {
opacity: 1;
-moz-transform: translate(0, 100px)scale(1.08, 0.92);
transform: translate(0, 100px)scale(1.08, 0.92);
}
60% {
opacity: 1;
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: translate(0, 45px);
transform: translate(0, 45px);
}
70% {
opacity: 1;
-moz-transform: translate(0, 100px)scale(1.05, 0.95);
transform: translate(0, 100px)scale(1.05, 0.95);
}
80% {
opacity: 1;
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: translate(0, 65px);
transform: translate(0, 65px);
}
85% {
opacity: 1;
-moz-transform: translate(0, 100px) scale(1.03, 0.97);
transform: translate(0, 100px) scale(1.03, 0.97);
}
90% {
opacity: 1;
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: translate(0, 80px);
transform: translate(0, 80px);
}
95% {
opacity: 1;
-moz-transform: translate(0, 100px) scale(1.01, 0.99);
transform: translate(0, 100px) scale(1.01, 0.99);
}
97% {
opacity: 1;
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: translate(0, 95px);
transform: translate(0, 95px);
}
100% {
opacity: 0;
-moz-transform: translate(0, 100px);
transform: translate(0, 100px);
}
}
@-webkit-keyframes diffuse-scale {
0% {
box-shadow: 0 14px 8px rgba(0, 0, 0, 0.5);
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: scale(1.5, 1) translateX(-50%);
}
15% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-webkit-transform: scale(1, 1) translateX(-50%);
}
30% {
box-shadow: 0 14px 7px rgba(0, 0, 0, 0.5);
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: scale(1.4, 1) translateX(-50%);
}
45% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-webkit-transform: scale(1, 1) translateX(-50%); }
60% {
box-shadow: 0 14px 5px rgba(0, 0, 0, 0.5);
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: scale(1.3, 1) translateX(-50%); }
70% {
box-shadow: 0 14 2px rgba(0, 0, 0, 0.5);
-webkit-transform: scale(1, 1) translateX(-50%);
}
80% {
box-shadow: 0 14px 4px rgba(0, 0, 0, 0.5);
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: scale(1.2, 1) translateX(-50%);
}
85% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-webkit-transform: scale(1, 1) translateX(-50%);
}
90% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: scale(1.1, 1) translateX(-50%);
}
95% {
box-shadow: 0 14px 3px rgba(0, 0, 0, 0.5);
-webkit-transform: scale(1, 1) translateX(-50%);
}
97% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-webkit-animation-timing-function: cubic-bezier(1, 0, 1, 1);
-webkit-transform: scale(1.05, 1) translateX(-50%);
}
100% {
-webkit-transform: scale(1, 1) translateX(-50%);
}
}
@keyframes diffuse-scale {
0% {
box-shadow: 0 14px 8px rgba(0, 0, 0, 0.5);
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: scale(1.5, 1) translateX(-50%);
transform: scale(1.5, 1) translateX(-50%);
}
15% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-moz-transform: scale(1, 1) translateX(-50%);
transform: scale(1, 1) translateX(-50%);
}
30% {
box-shadow: 0 14px 7px rgba(0, 0, 0, 0.5);
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: scale(1.4, 1) translateX(-50%);
transform: scale(1.4, 1) translateX(-50%);
}
45% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-moz-transform: scale(1, 1) translateX(-50%);
transform: scale(1, 1) translateX(-50%);
}
60% {
box-shadow: 0 14px 5px rgba(0, 0, 0, 0.5);
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: scale(1.3, 1) translateX(-50%);
transform: scale(1.3, 1) translateX(-50%);
}
70% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-moz-transform: scale(1, 1) translateX(-50%);
transform: scale(1, 1) translateX(-50%);
}
80% {
box-shadow: 0 14px 4px rgba(0, 0, 0, 0.5);
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: scale(1.2, 1) translateX(-50%);
transform: scale(1.2, 1) translateX(-50%);
}
85% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-webkit-transform: scale(1, 1) translateX(-50%);
-moz-transform: scale(1, 1) translateX(-50%);
transform: scale(1, 1) translateX(-50%);
}
90% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: scale(1.1, 1) translateX(-50%);
transform: scale(1.1, 1) translateX(-50%);
}
95% {
box-shadow: 0 14px 3px rgba(0, 0, 0, 0.5);
-moz-transform: scale(1, 1) translateX(-50%);
transform: scale(1, 1) translateX(-50%);
}
97% {
box-shadow: 0 14px 2px rgba(0, 0, 0, 0.5);
-moz-animation-timing-function: cubic-bezier(1, 0, 1, 1);
animation-timing-function: cubic-bezier(1, 0, 1, 1);
-moz-transform: scale(1.05, 1) translateX(-50%);
transform: scale(1.05, 1) translateX(-50%);
}
100% {
-moz-transform: scale(1, 1) translateX(-50%);
transform: scale(1, 1) translateX(-50%);
}
}
@-webkit-keyframes displace {
from {
-webkit-animation-timing-function: linear;
-webkit-transform: translateX(0);
}
to {
-webkit-transform: translateX(100px);
}
}
@keyframes displace {
from {
-moz-animation-timing-function: linear;
animation-timing-function: linear;
-moz-transform: translateX(0);
transform: translateX(0);
}
to {
-moz-transform: translateX(100px);
transform: translateX(100px);
}
}
.jump {
-webkit-animation-name: jump;
-moz-animation-name: jump;
-ms-animation-name: jump;
-o-animation-name: jump;
animation-name: jump;
}
.diffuse-scale {
-webkit-animation-name: diffuse-scale;
-moz-animation-name: diffuse-scale;
-ms-animation-name: diffuse-scale;
-o-animation-name: diffuse-scale;
animation-name: diffuse-scale;
}
.displace {
-webkit-animation-name: displace;
-moz-animation-name: displace;
-ms-animation-name: displace;
-o-animation-name: displace;
animation-name: displace;
}
<div class="wrapper">
<div class="content animated infinite displace">
<span class="ball animated infinite jump"></span>
<span class="ball-shadow animated infinite diffuse-scale"></span>
</div>
</div>
建议
像 less 或 SCSS 之类的东西,定义了恒定的物理变量,或者你可以添加到函数中并总结物理行为的值,甚至可能已经有模拟某些行为的 mixin,我不知道一些简单的东西,只有 CSS .
【问题讨论】:
-
您有两个选择,您可以使用 java 脚本实现真实的物理规则,也可以使用数学函数来模拟弹跳。实际上,球应该遵循抛物线,并且应该具有恒定的加速度。我认为您应该尝试使用二次动画
-
@vihan1086 我想要的是用css模拟“尽可能真实”的物理事件,例如球落下
-
它应该尽可能接近this...
-
类似这样的 js -- jsfiddle.net/3c6vps3j -- 摘自本指南 -- bassistance.de/2011/12/09/… -- 需要弄清楚如何停止球
-
这不是一个真正的答案,但如果想查找不同的 js 和 css 缓动,我使用以下站点:easings.net/de
标签: javascript html css css-animations