Javascript-форум (https://javascript.ru/forum/)
-   Мобильный JavaScript (https://javascript.ru/forum/mobile/)
-   -   Анимация ускорения вращения при скролле (https://javascript.ru/forum/mobile/80896-animaciya-uskoreniya-vrashheniya-pri-skrolle.html)

sergeantpepper 22.08.2020 11:50

Анимация ускорения вращения при скролле
 
Всем доброго времени!

Задача: Есть svg-геометрические фигуры, которые имеют равномерное вращение по часовой (скорость V1). При скролле вверх или вниз они должны ускорять свое вращение (скорость V2). Главным критерием является плавность и неторможение эффекта, иначе в нем теряется смысл.

Вот собранный стенд:
http://proudly.ru/febotelecom/#bl-services

Проблема сейчас в том, что анимация по советам была сделана через requestAnimationFrame, то есть девайс сам решает когда ему удобно перерисовать анимацию, но но мобайл устройствах при свайпе по-видимости мощи не хватает, и анимация вместо ускорения, наоборот, подвисает. Есть ли какие-то рецепты от опытных профессоров js анимаций? :)

Вот код:
var $services = $('#bl-services');
			$services.data('currRot', 0);
			var rotationV1 = 20;
			var rotationV2 = 100;
			var rotationTid = false;

			function servicesRotationCycle() {
				var currTs = Date.now();
				var dt = (currTs - $services.data('startTs')) / 1000;
				var rot = $services.data('startRot') + $services.data('speed') * dt;

				// debug
				//console.log('speed:', $services.data('speed'), 'rotation:', $services.data('startRot'), rot);

				$services.data('currRot', rot);

				$('#figure1').rotate({animateTo: Math.round(rot)});
				$('#figure2').rotate({animateTo: Math.round(rot)});
				$('#figure4').rotate({animateTo: Math.round(rot)});
				requestAnimationFrame(servicesRotationCycle);
			}

			function servicesRotationRegisterPoint(speed) {
				$services.data({
					'startTs': Date.now(),
					'startRot': $services.data('currRot'),
					'speed': speed,
				});
			}

			scrollCallbacks.push(function() {
				if (rotationTid) {
					clearTimeout(rotationTid);
				} else {
					servicesRotationRegisterPoint(rotationV2);					
				}
				rotationTid = setTimeout(function() {
					servicesRotationRegisterPoint(rotationV1);
					rotationTid = false;
				}, 50);
			});

			setTimeout(function() {
				servicesRotationRegisterPoint(rotationV1);
				requestAnimationFrame(servicesRotationCycle);
			}, 100);


Да, еще: используется Jquery.rotate (https://jqueryrotate.com/)

MallSerg 22.08.2020 14:15

43 - 46 строка.
Мне хочется плакать, ну или злобно юморить тыц

>> Проблема сейчас в том, что анимация по советам была сделана через requestAnimationFrame
Это утверждение не верно.

У тебя с определенными интервалами (43 строка) создаются задания т.е. функции которые должны быть вызваны при следующей отрисовке фрэйма.
Пока таких заданий(функций) на отрисовку 20-150 браузер успевает их выполнить каждый кадр. а когда становится около тысячи появляются заметные подтормаживания. Для анимирования достаточно будет только одного вызова анимирующей функции для каждого кадра.

Такие анимации гораздо лучше делать через CSS анимации. А со стороны JS просто изменять классы у элемента страницы для ускорения или замедления.

Древний примерчик использования requestAnimationFrame

sergeantpepper 23.08.2020 11:34

Цитата:

Сообщение от MallSerg (Сообщение 528174)
43 - 46 строка.
Мне хочется плакать, ну или злобно юморить тыц

>> Проблема сейчас в том, что анимация по советам была сделана через requestAnimationFrame
Это утверждение не верно.

У тебя с определенными интервалами (43 строка) создаются задания т.е. функции которые должны быть вызваны при следующей отрисовке фрэйма.
Пока таких заданий(функций) на отрисовку 20-150 браузер успевает их выполнить каждый кадр. а когда становится около тысячи появляются заметные подтормаживания. Для анимирования достаточно будет только одного вызова анимирующей функции для каждого кадра.

Такие анимации гораздо лучше делать через CSS анимации. А со стороны JS просто изменять классы у элемента страницы для ускорения или замедления.

Древний примерчик использования requestAnimationFrame

MallSerg, добрый день!

Нет, до такого я еще, конечно не дошел :)
На 43-46 всего лишь setTimeout(..., 100), был сделан для того, чтобы слегка отсрочить инициализацию. Хотя, признаться, я уже забыл зачем это было сделано.

По поводу CSS-анимаций думал и даже делал стенд с ней, но почему-то отмел этот вариант. Обязательно попробую его воспроизвести для сравнения.

sergeantpepper 24.08.2020 19:57

@MallSerg
Цитата:

Сообщение от MallSerg
Такие анимации гораздо лучше делать через CSS анимации. А со стороны JS просто изменять классы у элемента страницы для ускорения или замедления.

Попробовал реализовать через бесконечную css-анимацию:
http://proudly.ru/febotelecom/

В Css:
@mixin infinite-rotation($speed: $animation-speed) {
	-webkit-animation-name: rotation180;
    -webkit-animation-duration: $speed;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-timing-function: linear;
    -moz-animation-name: rotation;
    -moz-animation-duration: $speed;
    -moz-animation-iteration-count: infinite;
    -moz-animation-timing-function: linear;
    -o-animation-name: rotation180;
    -o-animation-duration: $speed;
    -o-animation-iteration-count: infinite;
    -o-animation-timing-function: linear;
    animation-name: rotation180;
    animation-duration: $speed;
    animation-iteration-count: infinite;
    animation-timing-function: linear;
}
@-webkit-keyframes rotation180 { to { -webkit-transform: rotate(180deg); }}
@-moz-keyframes rotation180 { to { -moz-transform: rotate(180deg); }}
@-ms-keyframes rotation180 { to { -ms-transform: rotate(180deg); }}
@-o-keyframes rotation360 { to { -o-transform: rotate(180deg); }}
@keyframes rotation180 { to { transform: rotate(180deg); }}

@mixin animation-duration($speed: $animation-speed) {
    -webkit-animation-duration: $speed;
    -moz-animation-duration: $speed;
    -o-animation-duration: $speed;
    animation-duration: $speed;
}

#figure1 {
		position: absolute;
		top: -18vw;
		right: -30.8vw;
		width: 58.343265792610250297973778307509vw;
		height: 59.356376638855780691299165673421vw;
		display: block;
		background: url('../images/_figure1.svg') no-repeat;
		background-size: contain;
		@include infinite-rotation(20000ms);

		&.accelerated {
			@include animation-duration(5000ms);
		}
}


Далее в скрипте при прокрутке просто навешивается класс accelerated , и по таймауту убирается при остановке прокрутки. Но почему-то при изменении свойства animation-duration почему-то анимация начинается сначала (или с какой-то альтернативной точки, не пойму). Это лечится?

MallSerg 24.08.2020 21:40

css transition

sergeantpepper 24.08.2020 23:56

Цитата:

Сообщение от MallSerg (Сообщение 528224)
css transition

MallSerg, нет, дело определенно не в этом:
http://proudly.ru/febotelecom/

Елена Кравченко 04.05.2021 10:41

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


Часовой пояс GMT +3, время: 00:35.