Ответ 1
Вы можете использовать только CSS, но вы потратите много времени на вычисление чисел для Bezier, позиций ключевого кадра, масштаба и т.д. Кроме того: небольшое изменение в вашем макете, "гравитация", размеры, расстояние, и вам нужно начинать "повсюду" (для вышеуказанной части как минимум).
CSS-анимации приятные, но вы получите лучший результат с небольшим кодом JavaScript, не говоря уже о том, что вам будет намного больше гибкости, если вам нужно что-то изменить -
- Определить вектор для шара
- Определить произвольную гравитацию
- Вычислить вектор и отскок
- Привязать результирующие значения к элементу DOM с помощью преобразований (дает более плавный результат по сравнению с позицией).
- Анимация с использованием
requestAnimationFrame
, которая синхронизируется для мониторинга и дает ровную плавную анимацию, как и анимация CSS.
Пример
В этом примере показано основное, не включает тень, но это остается как упражнение для читателя.
var div = document.querySelector("div"),
v = {x: 2.3, y: 1}, // some vector
pos = {x: 100, y: 20}, // some position
g = 0.5, // some gravity
absorption = 0.7, // friction/absorption
bottom = 150, // floor collision
frames = 0; // to reset animation (for demo)
// main calculation of the animation using a particle and a vector
function calc() {
pos.x += v.x; // update position with vector
pos.y += v.y;
v.y += g; // update vector with gravity
if (pos.y > bottom) { // hit da floor, bounce
pos.y = bottom; // force position = max bottom
v.y = -v.y * absorption; // reduce power with absorption
}
if (pos.x < 0 || pos.x > 620) v.x = -v.x;
}
// animate
(function loop() {
calc();
move(div, pos);
if (++frames > 220) { // tweak, use other techniques - just to reset bounce
frames = 0; pos.y = 20;
}
requestAnimationFrame(loop)
})();
function move(el, p) {
el.style.transform = el.style.webkitTransform = "translate("+p.x+"px,"+p.y+"px)";
}
div {
width:20px;
height:20px;
background:rgb(0, 135, 222);
border-radius:50%;
position:fixed;
}
<div></div>