仅使用 CSS 和 HTML 使球随着每次连续反弹的高度降低而反弹

Make a ball bounce with decreasing height of each successive bounce using just CSS and HTML

我正在尝试仅使用 HTML 和 CSS 让球反弹,希望不需要 Javascript。我能够通过一些水平运动进行简单的弹跳(参见 #ball)。贝塞尔曲线计时功能有助于使其自然。 但是,我无法使连续反弹的高度降低 - 参见 #ball2。 我尝试了以下方法(#ball 和#ball2 都显示在下面),但是 #ball2 的反弹看起来不自然。 (我还尝试为“控制”球的 div 的高度设置动画,但由于某种原因它不起作用。) 此外,还有另一个问题:当我在关键帧中为球的反弹高度设置 100% 时,它会测量球的高度,而不是父级 div,并取其中的 100%(所以 100% 100 像素)。
我怀疑在 #ball2 中反弹看起来不自然的主要原因是我在关键帧中错误地放置了贝塞尔曲线。我把 cubic-bezier(0.5, 1, 0.05, 0.5) 用于反弹的向上部分,但我认为这是不对的。我认为 cubic-bezier(0.5, 0.05, 1, 0.5) 适用于向下反弹(参见 #ball),并且“交替”的动画方向确保立方贝塞尔曲线适用于反向反弹的情况#ball。 (但是 #ball 反弹的高度没有变化。) 我试过在 #ball2 的情况下反弹的“缓出”计时功能,但它看起来仍然不正确。

html, body {
  height: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

body {
  display: flex;
 flex-direction: column;
  align-items: center;
}

#div1{
 width: 100vw;
 height: 100vh;
 background: gray;
  display: flex;
 flex-direction: column reverse;
align-items: flex-end;
  position: relative;
   animation: slide 3s linear forwards; 
}

#div2{
 width: 100%;
 height: 100%;
 background: gray;
  display: flex;
 flex-direction: column reverse;
 align-items: flex-end;
  position: absolute;
}

@keyframes slide{
  0%{ transform: translate3d(0, 0, 0);}
    10%{ transform: translate3d(-30px, 0, 0);}
    20%{ transform: translate3d(-60px, 0, 0);}
    30%{ transform: translate3d(-90px, 0, 0);}
    40%{ transform: translate3d(-120px, 0, 0);}
    50%{ transform: translate3d(-150px, 0, 0);}
    60%{ transform: translate3d(-180px, 0, 0);}
    70%{ transform: translate3d(-210px, 0, 0);}
    80%{ transform: translate3d(-240px, 0, 0);}
    90%{ transform: translate3d(-270px, 0, 0);}
    100%{ transform: translate3d(-300px, 0, 0);}
}

#ball{
    height: 100px;
    width: 100px;
    border-radius: 50%;
    right: 100px;
    top:200px;
    position: absolute;
    background-color:  pink;
    animation: bounce .5s alternate cubic-bezier(0.5, 0.05, 1, 0.50) 16;
    transform-box: border-box;
    }

@keyframes bounce {
  0%{transform:  translate(0,-200%);}
  100%{transform:  translate(0, 0);}
}

#ball2{
    height: 100px;
    width: 100px;
    border-radius: 50%;
    right: 100px;
    top:200px;
    position: absolute;
    background-color:  pink;
    animation: bounce2 2s,bezier 2s steps(6) ;
}

@keyframes bezier {
 0% {animation-timing-function: cubic-bezier(0.5, 0.05, 1, 0.50);}
 20% {animation-timing-function: cubic-bezier(0.5, 1, 0.05, 0.50);}
40% {animation-timing-function: cubic-bezier(0.5, 0.05, 1, 0.50);}
60% {animation-timing-function: cubic-bezier(0.5, 1, 0.05, 0.50);}
80% {animation-timing-function: cubic-bezier(0.5, 0.05, 1, 0.50);}
100% {animation-timing-function: cubic-bezier(0.5, 1, 0.05, 0.50);}
}

@keyframes bounce2 {
  0%{transform:  translate(0,-300%);} 
  20%{transform:  translate(0, 0);}
  40%{transform:  translate(0,-150%);}
  60%{transform:  translate(0, 0);}
  80% {transform:  translate(0,-75%);}
  100%{transform:  translate(0, 0);} 
}






   
<div id="div1">
   <div id="div2">
      <div id="ball2"></div>
   </div>
</div>

看起来没有系统的方法可以通过 CSS 和 HTML 以及像我尝试的那样使用贝塞尔曲线来实现这一点。 看看弹跳球的例子 Bouncing ball with CSS keyframes and Creating an Animated 3D Bouncing Ball with CSS3,如果想坚持 HTML 和 CSS,似乎唯一的方法就是尝试不同的高度和时间值,直到获得了正确的弹跳效果。他们在这些网站上取得了很好的成绩。

我尝试使用高度和宽度值。我觉得可以帮到你。

@keyframes bounce2 {
  0% {
    transform: translate(0, -300%);
    height: 120px;
  }
  12% {
    height: 120px;
  }
  20% {
    transform: translate(0, 0);
    height: 90px;
    width: 110px;
  }
  40% {
    transform: translate(0, -150%);
    height: 110px;
    width: 100px;
  }
  50% {
    height: 110px;
    width: 100px;
  }
  60% {
    transform: translate(0, 0);
    height: 95px;
    width: 105px;
  }
  80% {
    transform: translate(0, -75%);
    height: 95px;
  }
  100% {
    transform: translate(0, 0);
  }
}