Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 12.03.2019, 01:13
Аватар для Блондинка
Профессор
Отправить личное сообщение для Блондинка Посмотреть профиль Найти все сообщения от Блондинка
 
Регистрация: 24.02.2019
Сообщений: 806

CSS animation математический маятник
Есть специалисты по физике?
сделать анимацию не сложно, вопрос в другом, чисто по физике, как рассчитать траекторию маятника если известны первоначальный угол отклонения 90° длина нити 1м и ускорение под действием земного притяжения 9.8м/с.

надо высчитать на какой угол отклониться в противоположную сторону, и сколько надо времени для достижения этого угла, и второй момент - надо высчитать угол поворота через равные промежутки времени(например 0.1сек) для задания шагов анимации

просто дайте формулы для этих рассчётов.
Ответить с цитированием
  #2 (permalink)  
Старый 12.03.2019, 03:45
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 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.
Ответить с цитированием
  #3 (permalink)  
Старый 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сек.
просто дайте формулы для этих расчётов.
Ответить с цитированием
  #4 (permalink)  
Старый 13.03.2019, 19:00
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 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.
Ответить с цитированием
  #5 (permalink)  
Старый 13.03.2019, 19:21
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Malleys,
почему
Сообщение от Malleys
pendulumElement.style.setProperty("--θ",
а не сразу pendulumElement.style.setProperty("transform",
Ответить с цитированием
  #6 (permalink)  
Старый 13.03.2019, 19:35
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от рони Посмотреть сообщение
Malleys,
почему
а не сразу pendulumElement.style.setProperty("transform",
Так требуется, чтобы только маятник крутился, а не подставка с маятником!

Если я применю transform к .pendulum, то повернётся подставка, поэтому я придумал своё собственное свойство --θ, которое наследуется, и поэтому доступно в .pendulum::after, где я его могу применить в объявлении transform: rotate(var(--θ)); (обратите внимание, маятник представлен при помощи псевдо-элемента)

Последний раз редактировалось Malleys, 13.03.2019 в 19:48.
Ответить с цитированием
  #7 (permalink)  
Старый 13.03.2019, 19:43
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,064

Malleys,
спасибо, я упустил что там ::after, а для него нет отдельного style.
Ответить с цитированием
  #8 (permalink)  
Старый 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гр а взят из результата расчётов первой анимации, также высчитать шаги для второй анимации, потом для третьей и так до полного затухания

про скрипт для обновления анимации я спрашивала не только для этой конкретной анимации, а чтобы можно было бы добавить и для других анимаций который не имеют бесконечного повтора
Ответить с цитированием
  #9 (permalink)  
Старый 14.03.2019, 01:17
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от Блондинка
добавить префиксы
Вам не нужно добавлять префиксы, для этого можно использовать ⚡препроцессоры⚡, например autoprefixer https://github.com/postcss/autoprefixer или специальный скрипт, который добавит только необходимые браузеру префиксы, например, prefixfreehttps://leaverou.github.io/prefixfree/

Или вы любитель адского ☣CSS☣ с префиксами?

Сообщение от Блондинка
хотела сама все высчитать
Посмотрите в сторону препроцессоров, например, SASS, чтобы у вас не получился адски не управляемый ☣CSS☣. (Хотя с помощью скрипта вы тоже можете генерировать CSS в данном случае)

Последний раз редактировалось Malleys, 14.03.2019 в 03:48. Причина: Добавил autoprefixer
Ответить с цитированием
  #10 (permalink)  
Старый 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.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
отменить animation: для класса Black_Star (X)HTML/CSS 6 28.10.2016 10:06
css animation height ekkl-82 (X)HTML/CSS 17 30.10.2015 10:22
css анимация, плавный вовзрат к начальному значению FanAizu (X)HTML/CSS 0 30.01.2014 18:28
JQuery CSS анализатор javascript jQuery 2 15.08.2010 21:27
Подскажите по CSS меню Александр_1988 Элементы интерфейса 1 17.05.2010 11:58