Создание гравитационного эффекта в CSS-анимации падения и вычисление изменения радиуса «круга» при использовании rotateX - PullRequest
0 голосов
/ 28 января 2019

У меня есть следующая анимация, когда шар падает и отскакивает назад:

body {
  margin: 0;
  padding: 0;
}

.ball {
  width: 20px;
  height: 20px;
  
  margin: 0 auto;
  
  border-radius: 50%;
  background-color: black;
  
  animation: bounce 2s infinite linear;
}

.ground {
  display: block;
  width: 100%;
  
  border-bottom: 1px solid black;
  position: absolute;
  top: 100px;
}

@keyframes bounce {
  0%,100% {
    transform: translateY(0);
  }
  
  20% {
    background-color: black;
    transform: translateY(40px);
  }
  
  50% {
    background-color: red;
    transform: translateY(84px) rotateX(45deg);
  }
  70% {
    background-color: black;
    transform: translateY(40px);
  }
}
<div class = "ball">
</div>

<div class = "ground">
</div>

Как видите, я пытался придать мячу «сжатый» эффект, когда он касается земли.Я должен был использовать от translateX до 84px, чтобы поддерживать касание мяча с землей.Я получил это 84px методом проб и ошибок.Есть ли формула, которую я могу использовать для вычисления смещения (например, 4px в этом случае)?

Мяч падает с линейной скоростью, я пытался использовать ease-in и ease иэто не сработало.Я также пробовал разные номера с cubic-bezier.com .Как мне сделать так, чтобы скорость увеличивалась вместе со временем из-за гравитационного ускорения и замедления, когда она отскакивает назад?

1 Ответ

0 голосов
/ 28 января 2019

Проверьте решение ниже, если вы ненавидите математику 1

Поскольку вы вращаете элемент 45deg, у вас что-то вроде этого:

enter image description here

Вам нужна зеленая линия, которую можно получить по следующей формуле:

width/2 - X

Где

X = Width/2*cos(45deg)

, поэтому у вас будет Width/2*(1 - cos(45deg)) ~ Width/2*(1 - 0.707)

Затем вы можете отрегулировать процентное значение для управления скоростью.В качестве примечания вы должны получить не начальное, а более низкое значение, чтобы получить более реалистичную анимацию:

body {
  margin: 0;
  padding: 0;
}

.ball {
  width: 20px;
  height: 20px;
  
  margin: 0 auto;
  
  border-radius: 50%;
  background-color: black;
  
  animation: bounce 2s infinite ease-in;
}

.ground {
  display: block;
  width: 100%;
  
  border-bottom: 1px solid black;
  position: absolute;
  top: 100px;
}

@keyframes bounce {
  0% {
    transform: translateY(0);
  }
  
  30% {
    background-color: black;
    transform: translateY(80px);
  }
  
  40% {
    background-color: red;
    transform: translateY(calc(80px + 10px*(1 - 0.707))) rotateX(45deg);
  }
  
  50% {
    background-color: black;
    transform: translateY(80px);
  }
  100% {
    background-color: black;
    transform: translateY(50px);
  }
}
<div class = "ball">
</div>

<div class = "ground">
</div>

1 Вы также можете избежать вычислений, просто изменив transform-origin для поворота снизу, таким образомпространство будет уменьшено сверху:

body {
  margin: 0;
  padding: 0;
}

.ball {
  width: 20px;
  height: 20px;
  
  margin: 0 auto;
  
  border-radius: 50%;
  background-color: black;
  
  animation: bounce 2s infinite linear;
  transform-origin:bottom;
}

.ground {
  display: block;
  width: 100%;
  
  border-bottom: 1px solid black;
  position: absolute;
  top: 100px;
}

@keyframes bounce {
  0% {
    transform: translateY(0);
  }
  
  30% {
    background-color: black;
    transform: translateY(78px);
  }
  
  40% {
    background-color: red;
    transform: translateY(80px) rotateX(45deg);
  }
  
  50% {
    background-color: black;
    transform: translateY(78px);
  }
  100% {
    background-color: black;
    transform: translateY(50px);
  }
}
<div class = "ball">
</div>

<div class = "ground">
</div>

Если вы хотите получить нереалистичный эффект отскока, вы можете попробовать это:

body {
  margin: 0;
  padding: 0;
}

.ball {
  width: 20px;
  height: 20px;
  
  margin: 0 auto;
  
  border-radius: 50%;
  background-color: black;
  
  animation: bounce 2s infinite linear;
  transform-origin:bottom;
}

.ground {
  display: block;
  width: 100%;
  
  border-bottom: 1px solid black;
  position: absolute;
  top: 100px;
}

@keyframes bounce {
  0%,100% {
    transform: translateY(0);
  }
  
  35%,65% {
    background-color: black;
    transform: translateY(40px);
  }
  
  45%,55% {
    background-color: black;
    transform: translateY(75px);
  }
  
  50% {
    background-color: red;
    transform: translateY(80px) rotateX(45deg);
  }


}
<div class = "ball">
</div>

<div class = "ground">
</div>
...