如何改进纯 CSS3 弹跳球动画
How to improve a pure CSS3 bouncing ball animation
作为一个更大的混合应用程序项目的一部分,我需要让用户通过点击编号为 0 到 9 的弹跳球来 select 一组四个数字。我不想笨拙带有物理引擎的应用程序,因此我选择使用纯 CSS3 动画。我的努力如下所示
body,html
{
margin:0;
padding:0;
background-color:black;
}
#stage{position:relative;}
.ball
{
position:absolute;
width:7vw;
height:7vw;
border-radius:50%;
display:flex;
justify-content:center;
align-content:center;
align-items:center;
margin:0;
padding:0;
}
@keyframes bounce
{
0% {transform:translateY(0);}
95% {transform:translateY(86vh);}
100% {transform:translateY(86vh);}
}
#ballZero
{
background: #f45342;
margin-left:1em;
animation:bounce 3s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballOne
{
background-color:lime;
margin-left:calc(2em + 7vw);
animation:bounce 2.7s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballTwo
{
background-color:aqua;
margin-left:calc(3em + 14vw);
animation:bounce 3.2s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel='stylesheet' href='matter.css'/>
<style>
body,html{margin:0;padding:0;font-family:arial;}
#stage
{
height:100vh;
width:100vw;
}
</style>
</head>
<body>
<div id='stage'>
<div class="ball" id='ballZero'>0</div>
<div class='ball' id='ballOne'>1</div>
<div class='ball' id='ballTwo'>2</div>
</div>
</body>
</html>
虽然这行得通,但结果并不顺利,而且我认识到 CSS 动画远不是我的强项。我怎样才能改进这个动画,使效果看起来更逼真——请记住,在真实情况下我需要 10 个球?尽管有100% {transform:translateY(86vh);}
,但为什么球一碰到底部就不会反弹?
body,html
{
margin:0;
padding:0;
background-color:black;
}
#stage{position:relative;}
.ball
{
position:absolute;
width:7vw;
height:7vw;
border-radius:50%;
display:flex;
justify-content:center;
align-content:center;
align-items:center;
margin:0;
padding:0;
}
@keyframes bounce
{
0% {transform:translateY(0);}
100% {transform:translateY(86vh);}
}
#ballZero
{
background: #f45342;
margin-left:1em;
animation:bounce 3s;
animation-direction:alternate;
animation-timing-function:ease-in;
animation-iteration-count:infinite;
}
#ballOne
{
background-color:lime;
margin-left:calc(2em + 7vw);
animation:bounce 2.7s;
animation-direction:alternate;
animation-timing-function:ease-in;
animation-iteration-count:infinite;
}
#ballTwo
{
background-color:aqua;
margin-left:calc(3em + 14vw);
animation:bounce 3.2s;
animation-direction:alternate;
animation-timing-function:ease-in;
animation-iteration-count:infinite;
}
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel='stylesheet' href='matter.css'/>
<style>
body,html{margin:0;padding:0;font-family:arial;}
#stage
{
height:100vh;
width:100vw;
}
</style>
</head>
<body>
<div id='stage'>
<div class="ball" id='ballZero'>0</div>
<div class='ball' id='ballOne'>1</div>
<div class='ball' id='ballTwo'>2</div>
</div>
</body>
</html>
如果我们为向上和向下飞行添加稍微不同的计时功能,我们会得到更多的弹跳效果 - 当然是在地面弹跳上。
@keyframes bounce
{
0% {transform:translateY(0); animation-timing-function: ease-in;}
60% {transform:translateY(86vh); animation-timing-function: ease-out;}
100% {transform:translateY(0); animation-timing-function: ease-in;}
}
尝试使用三次贝塞尔定时函数,我们可能会得到更好的结果——尽管这似乎是一个实验领域。
这是应用上述函数的结果:
body,html
{
margin:0;
padding:0;
background-color:black;
}
#stage{position:relative;}
.ball
{
position:absolute;
width:7vw;
height:7vw;
border-radius:50%;
display:flex;
justify-content:center;
align-content:center;
align-items:center;
margin:0;
padding:0;
}
@keyframes bounce
{
0% {transform:translateY(0); animation-timing-function: ease-in;}
60% {transform:translateY(86vh); animation-timing-function: ease-out;}
100% {transform:translateY(0); animation-timing-function: ease-in;}
}
#ballZero
{
background: #f45342;
margin-left:1em;
animation:bounce 3s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballOne
{
background-color:lime;
margin-left:calc(2em + 7vw);
animation:bounce 2.7s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballTwo
{
background-color:aqua;
margin-left:calc(3em + 14vw);
animation:bounce 3.2s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
body,html{margin:0;padding:0;font-family:arial;}
#stage
{
height:100vh;
width:100vw;
}
<div id='stage'>
<div class="ball" id='ballZero'>0</div>
<div class='ball' id='ballOne'>1</div>
<div class='ball' id='ballTwo'>2</div>
</div>
作为一个更大的混合应用程序项目的一部分,我需要让用户通过点击编号为 0 到 9 的弹跳球来 select 一组四个数字。我不想笨拙带有物理引擎的应用程序,因此我选择使用纯 CSS3 动画。我的努力如下所示
body,html
{
margin:0;
padding:0;
background-color:black;
}
#stage{position:relative;}
.ball
{
position:absolute;
width:7vw;
height:7vw;
border-radius:50%;
display:flex;
justify-content:center;
align-content:center;
align-items:center;
margin:0;
padding:0;
}
@keyframes bounce
{
0% {transform:translateY(0);}
95% {transform:translateY(86vh);}
100% {transform:translateY(86vh);}
}
#ballZero
{
background: #f45342;
margin-left:1em;
animation:bounce 3s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballOne
{
background-color:lime;
margin-left:calc(2em + 7vw);
animation:bounce 2.7s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballTwo
{
background-color:aqua;
margin-left:calc(3em + 14vw);
animation:bounce 3.2s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel='stylesheet' href='matter.css'/>
<style>
body,html{margin:0;padding:0;font-family:arial;}
#stage
{
height:100vh;
width:100vw;
}
</style>
</head>
<body>
<div id='stage'>
<div class="ball" id='ballZero'>0</div>
<div class='ball' id='ballOne'>1</div>
<div class='ball' id='ballTwo'>2</div>
</div>
</body>
</html>
虽然这行得通,但结果并不顺利,而且我认识到 CSS 动画远不是我的强项。我怎样才能改进这个动画,使效果看起来更逼真——请记住,在真实情况下我需要 10 个球?尽管有100% {transform:translateY(86vh);}
,但为什么球一碰到底部就不会反弹?
body,html
{
margin:0;
padding:0;
background-color:black;
}
#stage{position:relative;}
.ball
{
position:absolute;
width:7vw;
height:7vw;
border-radius:50%;
display:flex;
justify-content:center;
align-content:center;
align-items:center;
margin:0;
padding:0;
}
@keyframes bounce
{
0% {transform:translateY(0);}
100% {transform:translateY(86vh);}
}
#ballZero
{
background: #f45342;
margin-left:1em;
animation:bounce 3s;
animation-direction:alternate;
animation-timing-function:ease-in;
animation-iteration-count:infinite;
}
#ballOne
{
background-color:lime;
margin-left:calc(2em + 7vw);
animation:bounce 2.7s;
animation-direction:alternate;
animation-timing-function:ease-in;
animation-iteration-count:infinite;
}
#ballTwo
{
background-color:aqua;
margin-left:calc(3em + 14vw);
animation:bounce 3.2s;
animation-direction:alternate;
animation-timing-function:ease-in;
animation-iteration-count:infinite;
}
<!DOCTYPE html>
<html>
<head>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link rel='stylesheet' href='matter.css'/>
<style>
body,html{margin:0;padding:0;font-family:arial;}
#stage
{
height:100vh;
width:100vw;
}
</style>
</head>
<body>
<div id='stage'>
<div class="ball" id='ballZero'>0</div>
<div class='ball' id='ballOne'>1</div>
<div class='ball' id='ballTwo'>2</div>
</div>
</body>
</html>
如果我们为向上和向下飞行添加稍微不同的计时功能,我们会得到更多的弹跳效果 - 当然是在地面弹跳上。
@keyframes bounce
{
0% {transform:translateY(0); animation-timing-function: ease-in;}
60% {transform:translateY(86vh); animation-timing-function: ease-out;}
100% {transform:translateY(0); animation-timing-function: ease-in;}
}
尝试使用三次贝塞尔定时函数,我们可能会得到更好的结果——尽管这似乎是一个实验领域。 这是应用上述函数的结果:
body,html
{
margin:0;
padding:0;
background-color:black;
}
#stage{position:relative;}
.ball
{
position:absolute;
width:7vw;
height:7vw;
border-radius:50%;
display:flex;
justify-content:center;
align-content:center;
align-items:center;
margin:0;
padding:0;
}
@keyframes bounce
{
0% {transform:translateY(0); animation-timing-function: ease-in;}
60% {transform:translateY(86vh); animation-timing-function: ease-out;}
100% {transform:translateY(0); animation-timing-function: ease-in;}
}
#ballZero
{
background: #f45342;
margin-left:1em;
animation:bounce 3s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballOne
{
background-color:lime;
margin-left:calc(2em + 7vw);
animation:bounce 2.7s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
#ballTwo
{
background-color:aqua;
margin-left:calc(3em + 14vw);
animation:bounce 3.2s;
animation-direction:alternate;
animation-timing-function:ease;
animation-iteration-count:infinite;
}
body,html{margin:0;padding:0;font-family:arial;}
#stage
{
height:100vh;
width:100vw;
}
<div id='stage'>
<div class="ball" id='ballZero'>0</div>
<div class='ball' id='ballOne'>1</div>
<div class='ball' id='ballTwo'>2</div>
</div>