Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #11 (permalink)  
Старый 10.11.2023, 16:14
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

<div id="moved" style="position: absolute;width:30px;height: 30px;background: red;"></div>
    <br>
    <input type="button" onclick="but1()" value="кнопка 1"> <br>
    
    <script type="text/javascript">
let nclick = 0;
const animparams = [
	[800 , 100 , 3000],
	[-750 , 10 , 200],
	[150 , -60 , 2000],
	[-200 , -50 , 1000]
];
let animPromise = Promise.resolve();

function but1 (){
    const element = document.getElementById("moved");
   
    animPromise = animPromise.then (() => animateMove( element , ...animparams[(nclick++) % 4]));
}



function animateMove ( element , x , y , time = 1000){
	
    const startX = element.offsetLeft;
    const startY = element.offsetTop;
    const startTime = performance.now();
    return new Promise ( (resolve) => {
		const animate = function (timenow){
			let EA = (timenow - startTime) / time;
			if (EA > 1) EA = 1;
			element.style.left = startX + (x * EA) + "px";
			element.style.top = startY + (y * EA) + "px";
			if (EA == 1) {
				resolve()
			} else {
				requestAnimationFrame(animate );
			}
		};
		animate(startTime);
    })
}

</script>

Жмите когда хотите и сколько хотите.
Можно и нормальную очередь сделать, хотя бы самую простую с помощью массива и операций push/shift. Добавлять в нее параметры следующей анимации и когда предыдущая закончится вытаскивать следующую. Ту главное принцип - ловить окончание анимации с помощью Promise.

Последний раз редактировалось voraa, 10.11.2023 в 17:36.
Ответить с цитированием
  #12 (permalink)  
Старый 11.11.2023, 17:04
Аспирант
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 74

Интересно. А вы не знаете почему это так работает? Ведь возвращение данных в then сохраняет эти данные для следующего then, а при возврате новых данных они просто заменятся. Но если возвращать промисы, то создаётся некое подобие очереди. Как так?
Ответить с цитированием
  #13 (permalink)  
Старый 11.11.2023, 18:16
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Сообщение от Raadsert
Но если возвращать промисы, то создаётся некое подобие очереди. Как так?
Именно так. Создается очередь из промисов. Когда исполняется один, начинает работать следущий (then всегда возвращает промис, но не тот же самый, к которому он применялся, а тот, который возвращает его функция)
Содается цепочка
anim1.then(()=>anim2).then(()=>anim3).... .then(()=>animN)

Последний раз редактировалось voraa, 11.11.2023 в 18:18.
Ответить с цитированием
  #14 (permalink)  
Старый 11.11.2023, 20:51
Аспирант
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 74

Вы ещё упоминали, что у threejs есть свои средства реализации подобного. А какие? Насколько я понимаю, реализовать способ с промисами, в непрерывном цикле - не получиться.
Ответить с цитированием
  #15 (permalink)  
Старый 11.11.2023, 21:26
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Сообщение от Raadsert
Вы ещё упоминали, что у threejs есть свои средства реализации подобного
Я сказал только что есть, раз они это как то реализуют. Я с ним не работал.
Ответить с цитированием
  #16 (permalink)  
Старый 12.11.2023, 00:59
Аспирант
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 74

А есть предположения как такое может реализоваться в непрерывном цикле?
Ответить с цитированием
  #17 (permalink)  
Старый 12.11.2023, 09:36
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Сообщение от Raadsert
А есть предположения как такое может реализоваться в непрерывном цикле?
На чем? (с threejs я не работал)
Что "такое"?
Ответить с цитированием
  #18 (permalink)  
Старый 13.11.2023, 12:04
Аспирант
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 74

Сообщение от voraa Посмотреть сообщение
На чем? (с threejs я не работал)
Что "такое"?
"Такое" - очередь как в промисах.
На обычном JS, как пример ваш код для цикличной анимации:

let tbeg;
let tlast;
 
function animate(t) {
	tbeg ??= t;
	tlast ?? = t
	const dtbeg = t - tbeg; // прошло от начала анимации
	const dtlast = t - tlast; // прошло от прошлой анимации
    render();  // расчет и внесение изменений с учетом dtbeg и/или dtlast
    tlast = t;
    if (какое то условие окончания) return;  // Завершить анимацию?
    requestAnimationFrame(animate);
    
}
 
function render() {
    // код для анимации каких ни будь элементов
}

animate(performance.now())


Понятное дело мы можем запускать его только когда нужна анимация. Но давайте предположи что его нельзя прервать (так работает threejs), как бы вы тогда добавили подобную (как в промисах) очередь?
Ответить с цитированием
  #19 (permalink)  
Старый 13.11.2023, 15:29
Профессор
Отправить личное сообщение для Rise Посмотреть профиль Найти все сообщения от Rise
 
Регистрация: 07.11.2013
Сообщений: 4,660

Raadsert,
Используй tween/tweening, напиши свой класс или возьми готовый tween.js, там ты сможешь chain-ы делать.
Ответить с цитированием
  #20 (permalink)  
Старый 13.11.2023, 16:58
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Я не понимаю, о чем вы спрашиваете (и не знаю, как в threejs).
Есть непрерывный цикл в браузере. Выполняется таск(обработка событий), потом микротаски, потом снова таск, снова микротоски и так далее.... Когда подходит время обновления экрана (с частотой ~16,6 ms или 8.3 ms) между микротасками и таском вклинивается рендер - обновление экрана. Это непрерывный цикл. Его нельзя прервать.
Если мне нужна анимация, я с помощью requestAnimationFrame задаю функцию, которая будет вызвана перед рендером. Эта функция снова может вызвать requestAnimationFrame, задав себя, что бы быть вызванной перед следующим рендером, если нужно. Так задается конкретная анимация.
Если мне нужно несколько одновременных анимаций, я могу несколько раз вызвать requestAnimationFrame и задать несколько функций, реализующих анимации. И все они будут вызываться перед рендером.
Если нужно ждать, когда одна анимация закончится, что бы что то сделать, например, запустить следующую, можно организовать возврат промиса.
Это основы.
Что конкретно вас интересует, я так и не могу понять.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перевод SMIL анимации в JS Black_Star Общие вопросы Javascript 9 14.02.2017 18:25
Поимать окончание анимации и вывести картинку. karssen Элементы интерфейса 2 10.12.2015 16:20
Начало анимации с места предыдущей анимации FanAizu (X)HTML/CSS 3 21.03.2014 11:39
Очередь XML запросов Евгений М AJAX и COMET 4 01.02.2012 10:05
После анимации очистить очередь virtus jQuery 2 19.12.2009 11:35