Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 08.11.2023, 08:59
Аспирант
Отправить личное сообщение для Raadsert Посмотреть профиль Найти все сообщения от Raadsert
 
Регистрация: 09.12.2021
Сообщений: 74

Очередь анимации в цикличном requestAnimationFrame
Подскажите, как можно реализовать очередь для анимации если используется цикличный requestAnimationFrame?

function animate() {
    render();
    requestAnimationFrame(animate);
}

function render() {
    // код для анимации каких ни будь элементов
}

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

Во-первых в функции animate должна быть проверка на то, что анимация должна остановиться. Т.е. вызывать requestAnimationFrame больше не нужно, иначе получится бесконечный цикл.
Во-вторых у функции animate есть параметр - время. Его надо использовать, что бы узнавать время от начала анимации или от предыдущего вызова animate, что бы рассчитывать какие произвести изменения.

Условная схема такая
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())


Примеры можно посмотреть тут
https://developer.mozilla.org/en-US/...AnimationFrame

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

Сообщение от voraa Посмотреть сообщение
Во-первых в функции animate должна быть проверка на то, что анимация должна остановиться. Т.е. вызывать requestAnimationFrame больше не нужно, иначе получится бесконечный цикл.
Во-вторых у функции animate есть параметр - время. Его надо использовать, что бы узнавать время от начала анимации или от предыдущего вызова animate, что бы рассчитывать какие произвести изменения.

Условная схема такая
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())


Примеры можно посмотреть тут
https://developer.mozilla.org/en-US/...AnimationFrame
Во первых, в Three.js анимация не останавливается, цикл отрисовки идёт бесконечно (возможно за исключением тех моментов когда окно сайта не активно). Во вторых, а как сделать то очередь из функций для анимации в таком цикле? Если к примеру, нужно чтоб после завершения одной анимации, начиналась другая. Разумеется не останавливая цикла и не создавая новый.
Ответить с цитированием
  #4 (permalink)  
Старый 08.11.2023, 11:44
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Если вы используете Three.js, то и пользуйтесь тем, что он дает.
Цикл отрисовки вообще не останавливается. Каждые 1/60 сек (при частоте экрана 60гц) происходит перерисовка экрана с учетом тех изменений, которые были внесены (если браузер не занят орбаботкой длинной задачи).
requestAnimationFrame просто дает возможность внести изменения перед перерисовкой с учетом времени.
Он представляет базовый уровень, на основе которого можно сделать что угодно, но это именно надо делать самому.
Вызовов requestAnimationFrame может быть много (много циклов). И когда наступает время перерисовки страницы, вызываются все функции, зарегистрированные к этому моменту.

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

Сообщение от voraa Посмотреть сообщение
Если вы используете Three.js, то и пользуйтесь тем, что он дает.
Цикл отрисовки вообще не останавливается. Каждые 1/60 сек (при частоте экрана 60гц) происходит перерисовка экрана с учетом тех изменений, которые были внесены (если браузер не занят орбаботкой длинной задачи).
requestAnimationFrame просто дает возможность внести изменения перед перерисовкой с учетом времени.
Он представляет базовый уровень, на основе которого можно сделать что угодно, но это именно надо делать самому.
Вызовов requestAnimationFrame может быть много (много циклов). И когда наступает время перерисовки страницы, вызываются все функции, зарегистрированные к этому моменту.
Но увеличение количества циклов сильно снижают производительность. Даже тот же Three.js, писался на нативном js. Вот мне и интересно, как можно реализовать очередь анимаций в постоянном цикле.
Ответить с цитированием
  #6 (permalink)  
Старый 08.11.2023, 12:04
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Сообщение от Raadsert
Но увеличение количества циклов сильно снижают производительность.
Ничего они сильно не снижают. Просто перед перерисовкой будут вызываться несколько простых функций, каждая отвечающая за свое изменение анимации, вместо одной сложной, которая делает все изменения.

Зачем постоянный цикл? Если нет изменений, то и вызывать ничего не надо. Когда есть какие то изменения, то для них запускается цикл requestAnimationFrame

Сообщение от Raadsert
Даже тот же Three.js, писался на нативном js
А на чем еще можно?

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

Сообщение от voraa Посмотреть сообщение
Ничего они сильно не снижают. Просто перед перерисовкой будут вызываться несколько простых функций, каждая отвечающая за свое изменение анимации, вместо одной сложной, которая делает все изменения.

Зачем постоянный цикл? Если нет изменений, то и вызывать ничего не надо. Когда есть какие то изменения, то для них запускается цикл requestAnimationFrame

А на чем еще можно?
Хорошо, тогда давайте будем отталкиваться от Three.js. Не знаете как можно сделать очередь анимаций для Three.js?
Ответить с цитированием
  #8 (permalink)  
Старый 09.11.2023, 18:36
Аватар для MallSerg
Профессор
Отправить личное сообщение для MallSerg Посмотреть профиль Найти все сообщения от MallSerg
 
Регистрация: 07.03.2011
Сообщений: 1,126

>>Хорошо, тогда давайте будем отталкиваться от Three.js. Не знаете как можно сделать очередь анимаций для Three.js?

Так же как и всегда запускать следующую анимацию после окончания предыдущей и так в порядке очереди.
Возможно у тебя возникли сложности с определением события "конец анимации"?.

Как пример простого вызова последовательных анимаций мой пост 10ти летней давности =).
https://javascript.ru/forum/misc/496...tml#post326928
Ответить с цитированием
  #9 (permalink)  
Старый 10.11.2023, 09:32
Аватар для voraa
Профессор
Отправить личное сообщение для voraa Посмотреть профиль Найти все сообщения от voraa
 
Регистрация: 03.02.2020
Сообщений: 2,682

Сообщение от MallSerg
Как пример простого вызова последовательных анимаций мой пост 10ти летней давности =).
https://javascript.ru/forum/misc/496...tml#post326928
Немного упростил и осовременил (с Promise и async/await)
<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">
function but1 (){
    const element = document.getElementById("moved");
    animateMove( element , 800 , 100 , 1500)
	.then ( () => animateMove( element , -750 , 10 , 200) )
	.then ( () => animateMove( element , 150 , -60 , 1000) )
	.then ( () => {    
			element.style.background = ("#" + ( Math.random() * (999-100)+100 )).substr(0,4) ;
			element.style.top = "30px";
			element.style.left = "100px";
		})
}

/*  С async/await  
async function but1 (){
    const element = document.getElementById("moved");
    await animateMove( element , 800 , 100 , 1500);
    await animateMove( element , -750 , 10 , 200);
    await animateMove( element , 150 , -60 , 1000);
    
    element.style.background = ("#" + ( Math.random() * (999-100)+100 )).substr(0,4) ;
    element.style.top = "30px";
    element.style.left = "100px";
}
*/

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

</script>

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

Я имею ввиду несколько другое понятие очереди. Например этот же код (я его немного исправил), если несколько раз нажимать на кнопку - анимация будет воспроизводится по новой. А вот каким образом сделать так, чтоб каждое нажатие на кнопку ставило запуск новой функции анимации в некую очередь, и анимация воспроизводилась одна после другой?

1 нажатие на кнопку => animate()
2 нажатие на кнопку => animate() animate()
3 нажатие на кнопку => animate(), animate(), animate()
(при условии что анимация вызванная первым нажатием ещё не завершилась)



<div id="moved" style="position: absolute;width:30px;height: 30px;background: red; pointer-events: none;"></div>
    <br>
    <input type="button" onclick="but1()" value="кнопка 1"> <br>

    <script type="text/javascript">
        function but1 (){
            const element = document.getElementById("moved");
            animateMove( element , 500 , 100 , 1500)
        }

        /*  С async/await
        async function but1 (){
            const element = document.getElementById("moved");
            await animateMove( element , 800 , 100 , 1500);
            await animateMove( element , -750 , 10 , 200);
            await animateMove( element , 150 , -60 , 1000);

            element.style.background = ("#" + ( Math.random() * (999-100)+100 )).substr(0,4) ;
            element.style.top = "30px";
            element.style.left = "100px";
        }
        */

        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){
                    const EA = (timenow - startTime) / time;
                    if (EA > 1) {
                        resolve();
                    } else {
                        element.style.translate = `${startX + (x * EA)}px ${startY + (y * EA)}px`;
                        requestAnimationFrame(animate);
                    }
                };
                animate(startTime);
            })
        }

    </script>

Последний раз редактировалось Raadsert, 10.11.2023 в 14:38.
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Перевод 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