Показать сообщение отдельно
  #11 (permalink)  
Старый 24.05.2019, 13:16
Аватар для Malleys
Профессор
Отправить личное сообщение для Malleys Посмотреть профиль Найти все сообщения от Malleys
 
Регистрация: 20.12.2009
Сообщений: 1,714

Сообщение от drkrol
В firefox, кстати, шаг одного прокручивания в 2 раза меньше. Даже в 2.5...
Это зависит от встроенного шага прокрутки, значит обычная прокрутка там в 2..2,5 раза медленней, по сравнению с тем, что вы обычно в другом месте видели... Эта скорость зависит от настроек ОП системы, в посте №7 я добавил переменную A, которая указывает во сколько раз ускорить встроенный шаг прокрутки...

Сообщение от drkrol
Может если за место
"transform", "translateY"
сделать GSAP, то подёргиваний не будет?
Какой смысл сюда тащить абстракцию, которая применит то же самый transform? Я проверил в Chrome, и в ПК и телефоне оно прокручивается идеально! В Firefox проверил... да, если приглядеться, то оно анимируется по пикселям, это поскольку в Firefox значения дробных пикселей округляются до целого числа. Т. е. не используется субпиксельный рендеринг, можно всё повернуть на 0,001°, чтобы использовался такой рендеринг.
<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width">
	<title>Document</title>
	<style>
		body {
			background: #20262E;
			font-family: "Helvetica Neue", system-ui;
		}

		.wrap-box {
			width: 290px;
			height: 290px;
			background: #777;
			margin: 10px;
		}

		body,
		html {
			height: 100%;
			margin: 0;
		}

		.wrap {
			overflow: auto;
			border: 1px solid red;
			box-sizing: border-box;
			height: 100%;
			scroll-behavior: unset;
			position: relative;
		}

		.wrap-content {
			overflow: hidden;
			height: 100%;
			position: -webkit-sticky;
			position: sticky;
			top: 0;
		}
		
		.boxes {
			will-change: transform;
			display: inline-block;
			width: 100%;
		}
		
		.height {
			position: absolute;
			top: 0;
			width: 1px;
		}
	</style>
</head>

<body>
	<div class="wrap">
		<div class="wrap-content">
			<div class="boxes"></div>
		</div>
		<div class="height"></div>
	</div>

	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
	<script>
		$(function() {
			for (var i = 0; i < 100; i++) {
				$(".boxes").append(`<div class="wrap-box">${1 + i}</div>`);
			}

			var T = 0.8; // время до торможения (секунды)
			var A = 5; // во сколько раз уменьшить полосу прокрутки? Лучше всего [1;5]

			var _top = 0;
			var top = 0;
			var height;
			var originalHeight, wrapHeight;
			var scrollTop = 0, _scrollTop = 0;
			var lastTime = performance.now();
			var isScrolling = false;
			
			var wrap = $(".wrap");
			var heightElement = $(".height");
			var boxes = $(".boxes");

			wrap.scroll(function(event) {
				event.preventDefault();
				_top = this.scrollTop;
				wrapHeight = wrap.height();
				if (!isScrolling) loop();
			});
			
			$(window).resize(function() {
				wrapHeight = wrap.height();
				originalHeight = boxes.height();
				height = Math.min(originalHeight - wrapHeight, (originalHeight - wrapHeight) / A) + wrapHeight;
				
				heightElement.css("height", height + "px");
				wrap.scroll();
			});
			
			$(window).resize();

			function loop() {
				isScrolling = true;
				var dt = -lastTime + (lastTime = performance.now());

				var a = 1 - Math.exp(-0.005 / T * dt);
				var p = _top / (height - wrapHeight);

				top = (1 - a) * top + a * _top;

				scrollTop = -top;
				boxes.css("transform", "translateY(" + (scrollTop + p * (A - 1) / A * (wrapHeight - originalHeight)) + "px) rotate(0.0001deg)");

				if (scrollTop !== _scrollTop) {
					requestAnimationFrame(loop);
					_scrollTop = scrollTop;
				} else
					isScrolling = false;
			}
		});
	</script>
</body></html>

Последний раз редактировалось Malleys, 24.05.2019 в 13:21.
Ответить с цитированием