12.03.2019, 01:13
|
|
Профессор
|
|
Регистрация: 24.02.2019
Сообщений: 806
|
|
CSS animation математический маятник
Есть специалисты по физике?
сделать анимацию не сложно, вопрос в другом, чисто по физике, как рассчитать траекторию маятника если известны первоначальный угол отклонения 90° длина нити 1м и ускорение под действием земного притяжения 9.8м/с.
надо высчитать на какой угол отклониться в противоположную сторону, и сколько надо времени для достижения этого угла, и второй момент - надо высчитать угол поворота через равные промежутки времени(например 0.1сек) для задания шагов анимации
просто дайте формулы для этих рассчётов.
|
|
12.03.2019, 03:45
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Дифференциальное уравнение, описывающее движение маятника
Если вам не нужна большая точность (для первоначального угла 90°), то можно ограничиться таким приближением (приближённым решением уравнения, выдаёт более точные результаты от -20° до 20°, вне пределов с некой погрешностью)
<div class="pendulum"></div>
<style>
.pendulum {
width: 1px;
height: 200px;
background: red;
display: flex;
flex-direction: column;
justify-content: flex-end;
transform-origin: 50% 0;
margin: auto;
}
.pendulum::after {
content: "";
display: block;
width: 10px;
height: 10px;
margin-left: -4.5px;
border-radius: 100%;
background: inherit;
}
</style>
<script>(function loop() {
document.querySelector(".pendulum").style.transform = `rotate(${0.5*Math.PI*Math.cos(Math.sqrt(9.8) * Date.now() / 1000)}rad)`;
requestAnimationFrame(loop);
})();</script>
Если необходимы более точные результаты, воспользуйтесь разложением Фурье... en.wikipedia.org/wiki/Pendulum_(mathematics) (или просмотрите всю статью)
Графики к упомянутому маятнику wolframalpha.com
Последний раз редактировалось Malleys, 12.03.2019 в 04:11.
|
|
12.03.2019, 20:59
|
|
Профессор
|
|
Регистрация: 24.02.2019
Сообщений: 806
|
|
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Математический маятник</title>
<style>
#a { width: 255px; height: 125px; background: #cfe6cf; border-radius: 15px/12px; border: 1px solid #c0c0c0; position: absolute; }
#b { width: 25px; height: 100px; display: inline-block; position: absolute; top: 15px; left: 122.5px; -webkit-transform-origin: 50% 0 ;-moz-transform-origin: 50% 0; -o-transform-origin: 50% 0; -ms-transform-origin: 50% 0; transform-origin: 50% 0; -webkit-animation: pendulum-1 1.79s linear 0s 1 normal forwards; -moz-animation: pendulum-1 1.79s linear 0s 1 normal forwards; -o-animation: pendulum-1 1.79s linear 0s 1 normal forwards; -ms-animation: pendulum-1 1.79s linear 0s 1 normal forwards; animation: pendulum-1 1.79s linear 0s 1 normal forwards; }
#c { width: 1px; height: 75px; background: #999999; position: absolute; left: 12px; }
#d { width: 1px; height: 1px; background: transparent; border-top: 15px solid #000080; border-left: 15px solid transparent; border-right: 15px solid transparent; border-bottom: 15px solid transparent; position: absolute; left: 120px; }
#U_2e { width: 25px; height: 25px; display: inline-block; border-radius: 50%; background: -moz-radial-gradient(60% 40%, circle cover, #9999ff 0%, #0000ff 100%); background: -webkit-radial-gradient(60% 40%, circle cover, #9999ff 0%, #0000ff 100%); background: -o-radial-gradient(60% 40%, circle cover, #9999ff 0%, #0000ff 100%); background: -ms-radial-gradient(60% 40%, circle cover, #9999ff 0%, #0000ff 100%); background: radial-gradient(60% 40%, circle cover, #9999ff 0%, #0000ff 100%); position: absolute; top: 75px; }
@-webkit-keyframes pendulum-1 { 0% { -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } 100% { -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); } }
@-moz-keyframes pendulum-1 { 0% { -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } 100% { -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); } }
@-o-keyframes pendulum-1 { 0% { -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } 100% { -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); } }
@-ms-keyframes pendulum-1 { 0% { -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } 100% { -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); } }
@keyframes pendulum-1 { 0% { -moz-transform: rotate(90deg); -ms-transform: rotate(90deg); -webkit-transform: rotate(90deg); -o-transform: rotate(90deg); transform: rotate(90deg); } 100% { -moz-transform: rotate(-45deg); -ms-transform: rotate(-45deg); -webkit-transform: rotate(-45deg); -o-transform: rotate(-45deg); transform: rotate(-45deg); } }
</style>
</head>
<body>
<div id="a">
<span id="d"></span>
<span id="b">
<span id="c"></span>
<span id="U_2e"></span>
</span>
</div>
</body>
</html>
вот анимация, надо высчитать правильный угол а не взятый примерно 45градусов и точное время вместо 1.79сек.
просто дайте формулы для этих расчётов.
|
|
13.03.2019, 19:00
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Блондинка
|
просто дайте формулы для этих расчётов
|
Сообщение от Блондинка
|
просто дайте формулы для этих расчётов
|
Если вам формулы «дадут», а не «просто дадут», то это какое-то другое значение будет для вас иметь?
Сообщение от Блондинка
|
дайте формулы
|
Рассмотрите внимательно пост №2
Сообщение от Блондинка
|
надо высчитать правильный угол
|
Это математический маятник, у него крайние значения угла отклонения не меняется со временем. В начале вы написали условия для маятника, среди которых было θ₀ = 90°, значит угол отклонения с противоположной стороны тоже составляет 90°.
Сообщение от Блондинка
|
надо высчитать... точное время
|
Также вы указали, что g = 9.8 и l = 1, статья, которую я вам указал, содержит практически всю информацию о математическом маятнике, включая формулу для вычисления периода колебания (вперёд и назад, полное колебание).
Подставим ваши данные, получается T = 2π ⋅ sqrt(1 / 9.8) ≈ 2 (сек.)
В CSS есть функция cubic-bezier(x₁, y₁, x₂, y₂), возможно ли при помощи неё выразить половину периода колебания маятника? Да, возможно! (Я не буду описывать, как это получается, вот рабочий лист с графиками https://www.desmos.com/calculator/qxtb8h7li7)
Математический маятник
<div class="pendulum"></div>
<style>
.pendulum {
width: 255px;
height: 125px;
background: #cfe6cf;
border-radius: 15px / 12px;
border: 1px solid #c0c0c0;
}
.pendulum::before {
content: "";
display: block;
width: 0;
margin: auto;
border: 15px solid transparent;
border-top-color: #000080;
border-bottom-width: 0;
}
.pendulum::after {
content: "";
display: block;
margin: auto;
width: 25px;
height: 100px;
background:
radial-gradient(closest-side circle at 50% 87.5%, #0000ff 90%, transparent),
linear-gradient(to right, transparent 47%, #999, transparent 53%)
;
--mask: radial-gradient(closest-side circle at 45% 84.5%, rgba(0, 0, 0, .3), black 136%);
-webkit-mask: var(--mask);
mask: var(--mask);
transform-origin: 50% 0;
animation: pendulum 1s alternate infinite cubic-bezier(0.36, 0, 0.646, 1);
}
@keyframes pendulum {
from {
transform: rotate(90deg);
}
to {
transform: rotate(-90deg);
}
}
</style>
Сообщение от Блондинка
|
надо высчитать... точное время
|
Оно равно θ(t), где t принимает значения 0, 1/2 * T, T, 3/2 * T, 2 * T, ..., k/2 * T; k ∈ N. Для математического маятника вы получите всегда одинаковые крайние значения, но можно построить маятник, который со временем придёт к состоянию равновесия из-за трения. Пусть функция выражающая количество энергии равна f(t) и представлена при помощи графика (зелёная пунктирная линия, см. рабочий лист). Тогда можно представить маятник с затухающими колебаниями при помощи f(t) ⋅ θ(t).
Сообщение от Блондинка
|
То самое, что я не могла найти, всё супер.
|
Вам только нужно, чтобы анимация запускалась или маятник правильно работал или то и другое?
Сообщение от Блондинка
|
как обновить див с анимацией по клику по самому диву без всяких кнопок
|
Так нажать по чему-то подразумевает, что вы попадёте на кнопку! Вы требуете странное, хотите нажать, но кнопку вам не надо! Это как хлопнуть в ладоши без ладошей! (Вы уже это где-то прочитали!) Да, оно работает с мышью, но оно не работает с клавиатуры, оно не работает на некоторых телефонах, оно не работает на Android TV, оно не воспринимается скинридерами как кнопка ... т. е. вы не сможете запустить свою анимацию заново!
Вот переделанный пример из поста №2... (с применением выше написанного)
Маятник с затухающим колебанием, запускается заново при нажатии на него
<button class="pendulum"></button>
<style>
.pendulum {
width: 255px;
background: #cfe6cf;
border-radius: 15px / 12px;
border: 1px solid #c0c0c0;
padding: 0;
display: block;
}
.pendulum::before {
content: "";
display: block;
width: 0;
margin: auto;
border: 15px solid transparent;
border-top-color: #000080;
border-bottom-width: 0;
}
.pendulum::after {
content: "";
display: block;
margin: auto;
margin-bottom: 8px;
width: 25px;
height: 100px;
background:
radial-gradient(closest-side circle at 50% 87.5%, #0000ff 90%, transparent),
linear-gradient(to right, transparent 47%, #999, transparent 53%)
;
--mask: radial-gradient(closest-side circle at 45% 84.5%, rgba(0, 0, 0, .3), black 136%);
-webkit-mask: var(--mask);
mask: var(--mask);
transform: rotate(var(--θ));
transform-origin: 50% 0;
}
</style>
<script>{
const pendulumElement = document.querySelector(".pendulum");
var startTime;
function setNewStartTime() {
startTime = Date.now() / 1000
}
setNewStartTime();
(function loop() {
const t = Date.now() / 1000 - startTime;
const θ = 0.5 * Math.PI * Math.cos(Math.sqrt(9.8) * t);
const f = Math.exp(-.25 / Math.PI * t * t);
pendulumElement.style.setProperty("--θ", `${f * θ}rad`);
requestAnimationFrame(loop);
})();
pendulumElement.addEventListener("click", setNewStartTime);
}</script>
Вы просите одно, а ожидаете другое. Формулируйте свои вопросы более точно, указывайте все подробности. Указывайте, что вы делали, что именно у вас не получается, и пусть это будет в одной теме!
UPD
Сообщение от Блондинка
|
Так?
|
Вы спрашиваете так, как будто это у меня что-то не получается, а вы якобы нашли решение, и вопрошаете, действительно ли мне такое подходит!
Последний раз редактировалось Malleys, 13.03.2019 в 19:31.
|
|
13.03.2019, 19:21
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,121
|
|
Malleys,
почему
Сообщение от Malleys
|
pendulumElement.style.setProperty("--θ",
|
а не сразу pendulumElement.style.setProperty("transform",
|
|
13.03.2019, 19:35
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от рони
|
Malleys,
почему
а не сразу pendulumElement.style.setProperty("transform",
|
Так требуется, чтобы только маятник крутился, а не подставка с маятником!
Если я применю transform к .pendulum, то повернётся подставка, поэтому я придумал своё собственное свойство --θ, которое наследуется, и поэтому доступно в .pendulum::after, где я его могу применить в объявлении transform: rotate(var(--θ)); (обратите внимание, маятник представлен при помощи псевдо-элемента)
Последний раз редактировалось Malleys, 13.03.2019 в 19:48.
|
|
13.03.2019, 19:43
|
|
Профессор
|
|
Регистрация: 27.05.2010
Сообщений: 33,121
|
|
Malleys,
спасибо, я упустил что там ::after, а для него нет отдельного style.
|
|
13.03.2019, 21:14
|
|
Профессор
|
|
Регистрация: 24.02.2019
Сообщений: 806
|
|
Malleys, пока я не могу посмотреть примеры, из-за браузера, надо скопировать на "сайт" и добавить префиксы, я хотела сама все высчитать, типа зная время и угол можно высчитать вторую анимацию с задержкой, хотела сначала высчитать сколько шагов анимации надо высчитав углы для шагов 0,20,40,60,80 100%, если результат не понравится добавить шаги 10,30,50,70,90%, если опять не понравится добавить еще промежуточные шаги по 5% и тд, это для одного колебания, для второго колебания (-45град 30 град образно) добавить вторую анимацию где начальный угол не 90гр а взят из результата расчётов первой анимации, также высчитать шаги для второй анимации, потом для третьей и так до полного затухания
про скрипт для обновления анимации я спрашивала не только для этой конкретной анимации, а чтобы можно было бы добавить и для других анимаций который не имеют бесконечного повтора
|
|
14.03.2019, 01:17
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от Блондинка
|
добавить префиксы
|
Вам не нужно добавлять префиксы, для этого можно использовать ⚡препроцессоры⚡, например autoprefixer https://github.com/postcss/autoprefixer или специальный скрипт, который добавит только необходимые браузеру префиксы, например, prefixfree ⛏ https://leaverou.github.io/prefixfree/ ⛱
Или вы любитель адского ☣CSS☣ с префиксами?
Сообщение от Блондинка
|
хотела сама все высчитать
|
Посмотрите в сторону препроцессоров, например, SASS, чтобы у вас не получился адски не управляемый ☣CSS☣. (Хотя с помощью скрипта вы тоже можете генерировать CSS в данном случае)
Последний раз редактировалось Malleys, 14.03.2019 в 03:48.
Причина: Добавил autoprefixer
|
|
14.03.2019, 09:41
|
|
Профессор
|
|
Регистрация: 24.02.2019
Сообщений: 806
|
|
Сообщение от Malleys
|
Вы просите одно, а ожидаете другое. Формулируйте свои вопросы более точно, указывайте все подробности.
|
я расчитывала что мне просто дадут формулы как высчитать время и угол отклонения в другую сторону при затухающих колебаниях, с подробными пояснениями этих формул
Сообщение от Malleys
|
Оно равно θ(t), где t принимает значения 0, 1/2 * T, T, 3/2 * T, 2 * T, ..., k/2 * T; k ∈ N.
|
с подробными пояснениями что значат буквы в этих формулах.
Сообщение от Malleys
|
Если вы хотели добавить префиксы, то вам ещё нужно добавить -webkit-border-radius и -moz-border-radius.
...............
|
исправила
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Математический маятник</title>
<style>
#mathematics_pendulum { width: 930px; height: 500px; background: -webkit-linear-gradient(top, #ade6ad, #e6e6cc); background: -moz-linear-gradient(top, #ade6ad, #e6e6cc); background: -o-linear-gradient(top, #ade6ad, #e6e6cc); background: linear-gradient(to top, #ade6ad, #e6e6cc); -webkit-border-radius: 50px/35px; border-radius: 50px/35px; border: 1px solid #c0c0c0; position: absolute; }
#still_point { width: 1px; height: 1px; background: transparent; border-top: 45px solid #000080; border-left: 45px solid transparent; border-right: 45px solid transparent; border-bottom: 45px solid transparent; position: absolute; left: 420px; }
#pendulum { width: 75px; height: 400px; display: inline-block; position: absolute; left: 428px; top: 45px; -webkit-transform-origin: 50% 0; -ms-transform-origin: 50% 0; transform-origin: 50% 0; }
#mathematics_pendulum.animation_demo #pendulum { -webkit-animation: pendulum-1 1.79s linear 0s 1 normal forwards; animation: pendulum-1 1.79s linear 0s 1 normal forwards; }
#pendulum_rod { width: 3px; height: 325px; background: #999999; border-radius: 2px; position: absolute; left: 36px; }
#point_pendulum { width: 75px; height: 75px; display: inline-block; -webkit-border-radius: 50%; border-radius: 50%; background: -webkit-radial-gradient(60% 40%, circle, #bfbfff, #00f); background: -o-radial-gradient(60% 40%, circle, #bfbfff, #00f); background: radial-gradient(circle at 60% 40%, #bfbfff, #00f); position: absolute; top: 325px; }
@-webkit-keyframes pendulum-1 { 0% { -webkit-transform: rotate(90deg); transform: rotate(90deg); } 100% { -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } } @keyframes pendulum-1 { 0% { -webkit-transform: rotate(90deg); transform: rotate(90deg); } 100% { -webkit-transform: rotate(-45deg); transform: rotate(-45deg); } }
</style>
</head>
</head>
<body>
<div id="mathematics_pendulum" class="animation_demo">
<span id="still_point"></span>
<span id="pendulum">
<span id="pendulum_rod"></span>
<span id="point_pendulum"></span>
</span>
</div>
<script>
var a = document.querySelector("#mathematics_pendulum"); a.addEventListener("click", function() { a.classList.remove("animation_demo"); document.documentElement.clientWidth; a.classList.add("animation_demo"); });
</script>
</body>
</html>
Сообщение от Malleys
|
Вы просите одно, а ожидаете другое. Формулируйте свои вопросы более точно, указывайте все подробности.
|
Сейчас надеюсь что помогут вставить скрипт маятника с затухающими колебаниями в код представленный выше в этом посте, но со всеми необходимыми префиксами...
<script>{
const pendulumElement = document.querySelector(".pendulum");
var startTime;
function setNewStartTime() {
startTime = Date.now() / 1000
}
setNewStartTime();
(function loop() {
const t = Date.now() / 1000 - startTime;
const θ = 0.5 * Math.PI * Math.cos(Math.sqrt(9.8) * t);
const f = Math.exp(-.25 / Math.PI * t * t);
pendulumElement.style.setProperty("--θ", `${f * θ}rad`);
requestAnimationFrame(loop);
})();
pendulumElement.addEventListener("click", setNewStartTime);
}</script>
Последний раз редактировалось Блондинка, 14.03.2019 в 10:22.
|
|
|
|