2015-06-06 6 views
12

Я просто занимаюсь загрузкой с использованием css, и я хочу, чтобы у них было реальное поведение, я пытаюсь использовать animation-timing-function: cubic-bezier(1, 0, 1, 1), выглядит отлично, но не так реально, как хочу, сначала, потому что я не знаю, как cubic-bezier параметры действительно работают, я нашел this сайт и просто играл с ними, пока не получил что-то хорошее.Как добавить физику в анимацию CSS?

Подводя итог, как добавить настоящее физическое поведение в мою анимацию?

ПОЖАЛУЙСТА, ТОЛЬКО CSS, если это невозможно, решение JS приветствуется.

У вас есть пример FIDDLE.

Просто предложение для руководства

что-то вроде меньше или SCSS с постоянными физическими переменными, которые определены или значением, которые вы можете добавить к функции и sumule физического поведения может даже иметь уже Примесь, что симулирует определенное поведение , Я не знаю ничего простого и только CSS.

Thx заранее

+0

CSS для физики? – Downgoat

+4

У вас есть два варианта: вы можете либо реализовать реальные правила физики с помощью java-скрипта, либо использовать математическую функцию для моделирования подпрыгивания. В действительности шар должен следовать параболической дуге и должен иметь постоянное ускорение. Я думаю, вы должны попробовать играть с квадратичной анимацией – steve

+0

@ vihan1086, что я хочу, чтобы имитировать «как можно более реальные» физические события с помощью css, например, падающий мяч –

ответ

10

Вы может использовать CSS-только, но вы будете тратить много времени на выяснение того, номер для Безье, ключевой кадр позиции, масштаба и так далее, и на вершине, что: небольшое изменение в вашем макете, «гравитация», размеры, расстояние, и вы должны начать «повсюду» (по крайней мере, для вышеуказанной части).

CSS анимации хороши, но вы получите лучший результат с небольшим количеством кода JavaScript, не говоря уже имеют гораздо большую гибкость, если вам нужно что-то изменить -

  • Определение вектора для шара
  • Определить произвольную гравитацию
  • Вычислить вектор и отказы
  • Bind полученных значения для элементов 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>

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

if (pos.y > bottom) { 
    var diff = pos.y - bottom; 
    pos.y = bottom - diff; 
    ... 

И если вам это нужно для нескольких элементов просто создайте объект, способный к созданию экземпляра, который включает ссылку на элемент для анимации, вычисления и т. д.

Если вы хотите изменить направление, начальную точку, гравитацию и т. Д., Вы просто обновляете соответствующие значения, и при повторном воспроизведении все будет работать плавно.

Пример промежуточный шаг для создания CSS ключевые кадры

Вы можете изменить код, чтобы грызть числа для CSS-анимации.

Использовать количество кадров и нормализовать диапазон последовательности, выполнить вычисления путем подсчета кадров. Затем извлекайте значения per, скажем, каждые 10 кадров, а также каждый отскок, наконец, цифры формата в виде ключевых кадров.

В идеале вы всегда будете включать верхнее и нижнее положение - вы можете обнаружить это, контролируя направление y-значения вектора (знак), не показанного здесь.

Это будет работать в качестве промежуточного шага для создания CSS-правила, которые мы будем использовать позже:

var 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) 
 
    maxFrames = 220,   // so we can normalize 
 
    step = 10,    // grab every nth + bounce 
 
    heights = [],    // collect in an array as step 1 
 
    css = "";     // build CSS animation 
 

 
// calc CSS-frames 
 
for(var i = 0; i <= maxFrames; i++) { 
 
    var t = i/maxFrames; 
 
    pos.x += v.x;    // update position with vector 
 
    pos.y += v.y; 
 
    v.y += g;     // update vector with gravity 
 

 
    if (pos.y > bottom) { 
 
    pos.y = bottom; 
 
    v.y = -v.y * absorption; 
 
    heights.push({pst: t * 100, y: pos.y}); 
 
    } 
 
    else if (!(i % step)) {heights.push({pst: t * 100, y: pos.y})} 
 
} 
 

 
// step 2: format height-array into CSS 
 
css += "@keyframes demo {\n"; 
 
for(i = 0; i < heights.length; i++) { 
 
    var e = heights[i]; 
 
    css += " " + e.pst.toFixed(3) + "% {transform: translateY(" + e.y.toFixed(3) + "px)}\n"; 
 
} 
 
css += "}"; 
 

 
document.write("<pre>" + css + "</pre>");

Если мы захватываем результат от этого и использует его в качестве CSS для нашего окончательная страница, мы получаем этот результат (извините, но не префиксная версия только в этой демонстрации):

(Вам, конечно, придется подстроить и настроить его, но вы получите суть.)

div { 
 
    animation: demo 3s linear infinite; 
 
    width:20px; 
 
    height:20px; 
 
    border-radius:50%; 
 
    background:rgb(0, 148, 243); 
 
    position:fixed; 
 
    left:100px; 
 
} 
 

 
@keyframes demo { 
 
    0.000% {transform: translateY(21.000px)} 
 
    4.545% {transform: translateY(58.500px)} 
 
    9.091% {transform: translateY(146.000px)} 
 
    9.545% {transform: translateY(150.000px)} 
 
    13.636% {transform: translateY(92.400px)} 
 
    18.182% {transform: translateY(75.900px)} 
 
    22.727% {transform: translateY(109.400px)} 
 
    25.455% {transform: translateY(150.000px)} 
 
    27.273% {transform: translateY(127.520px)} 
 
    31.818% {transform: translateY(106.320px)} 
 
    36.364% {transform: translateY(135.120px)} 
 
    37.727% {transform: translateY(150.000px)} 
 
    40.909% {transform: translateY(125.563px)} 
 
    45.455% {transform: translateY(133.153px)} 
 
    47.273% {transform: translateY(150.000px)} 
 
    50.000% {transform: translateY(134.362px)} 
 
    54.545% {transform: translateY(148.299px)} 
 
    55.000% {transform: translateY(150.000px)} 
 
    59.091% {transform: translateY(138.745px)} 
 
    61.818% {transform: translateY(150.000px)} 
 
    63.636% {transform: translateY(141.102px)} 
 
    67.727% {transform: translateY(150.000px)} 
 
    68.182% {transform: translateY(147.532px)} 
 
    72.727% {transform: translateY(150.000px)} 
 
    77.273% {transform: translateY(150.000px)} 
 
    81.818% {transform: translateY(150.000px)} 
 
    86.364% {transform: translateY(150.000px)} 
 
    90.909% {transform: translateY(150.000px)} 
 
    95.455% {transform: translateY(150.000px)} 
 
    100.000% {transform: translateY(150.000px)} 
 
}
<div></div>

Лично я бы рекомендовал поддержку JavaScript, хотя, как он является более точным для этих типов анимации, и, как уже упоминалось, он может легко адаптироваться к новым требованиям.

+0

Отличный ответ, безусловно, я отвечу на ваш совет. Очень признателен –

Смежные вопросы