Эффект плавной прокрутки при добавлении изображений с высоким разрешением на страницу - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь реализовать эффект плавной прокрутки, и у меня возникают проблемы при добавлении изображений высокого разрешения на страницу. Эффект плавный, пока я не добавлю изображения размером более 1 Мб. Когда вы впервые начинаете прокручивать страницу вниз, возникает сбой, и страница переходит на другую сторону. Это также происходит, когда вы фокусируете другую вкладку и затем возвращаетесь на страницу. В моем примере это может быть незначительно, но оно становится более выраженным, если я начну переводить эти изображения и создавать эффекты параллакса. Когда вы прокручиваете страницу вниз, браузер, кажется, выполняет оптимизацию, и после этого эффект плавный. Но первоначальная прокрутка вниз дает сбой. Я могу только предположить, что это проблема с краской или что-то в этом роде, но я понятия не имею, как это исправить.

Я использую requestAnimationFrame и уменьшаю значение y на свитке, чтобы я мог добавить элементы анимации, которые будут перемещаться с тем же Ослабив значение, я фиксирую контейнер и перемещаю его на основе ослабленного значения y.

Я видел очень плавные примеры такого типа эффекта, но, похоже, не могу его достичь. Правильный ли я подход или есть другая техника, которую я должен использовать? Любые идеи будут оценены.

Я пытался добавить will-change: transform к css контейнера, но безрезультатно.

Вот очень минимальный пример эффекта:

Codepen

// helper functions
const getRect = el => {
  return el.getBoundingClientRect();
};

const setStyles = (c, s) => {
  const height = getRect(c).height;
  c.style.position = 'fixed';
  c.style.left = '0';
  c.style.top = '0';
  c.style.width = '100%';
  s.style.height = height + 'px';
  s.style.width = '1px';
  s.style.position = 'relative';
};

const getWin = () => {
  const height = window.innerHeight;
  const width = window.innerWidth;
  const rem = parseInt(
    window.getComputedStyle(document.documentElement).fontSize
  );
  return {
    height,
    width,
    rem,
  };
};

//main controller function
const scrollController = function(opts){
	const ease = 0.09;
  const container = opts.container;
  const spacer = opts.spacer;
  let win = getWin();
  let ys = 0;
  let yc = ys;
  let AF = null;
  let tweens = [];
	
	const startAnimation = () => {
    if (!AF) AF = requestAnimationFrame(render);
  };

  const cancelAnimation = () => {
    yc = ys;
    cancelAnimationFrame(AF);
    AF = null;
  };
	
  const render = () => {
    const diff = ys - yc;
    const delta = Math.abs(diff) < 0.1 ? 0 : diff * ease;
    if (delta) {
      yc += delta;
      yc = parseFloat(yc.toFixed(2));
      updateElements();
      AF = requestAnimationFrame(render);
    } else {
      cancelAnimation();
    }
  };
	
	const updateElements = () => {
		container.style.transform = `translateY(${-yc}px)`;
	}
	
  const updateScroll = () => {
    ys = window.scrollY;
    startAnimation();
  };
	
	//initialize
	setStyles(container, spacer);
	window.addEventListener('scroll', updateScroll, false);
}

const controller = new scrollController({
	container: document.querySelector('.scroll-container'),
	spacer: document.querySelector('.spacer')
})
.container{
	margin: 0 auto;
	padding: 50px 0;
	max-width: 90%;
}

.wrapper{
	position:relative;
	height: 50vh;
	overflow:hidden;
}

.wrapper.first{
	height: 100vh;
}

.bg{
	position:absolute;
	bottom:0;
	left:0;
	width: 100%;
	height: 200%;
}

.one{
	background: url(https://image.tmdb.org/t/p/original/upUy2QhMZEmtypPW3PdieKLAHxh.jpg) no-repeat center / cover;
}

.two{
	background: url(https://image.tmdb.org/t/p/original/vsGummv4RDHurznV22UkumeI3fS.jpg) no-repeat center / cover;
}

.three{
	background: url(https://image.tmdb.org/t/p/original/ocUrMYbdjknu2TwzMHKT9PBBQRw.jpg) no-repeat center / cover;
}

.four{
	background: url(https://image.tmdb.org/t/p/original/lP5eKh8WOcPysfELrUpGhHJGZEH.jpg) no-repeat center / cover;
}

.five{
	background: url(https://image.tmdb.org/t/p/original/jiqD14fg7UTZOT6qgvzTmfRYpWI.jpg) no-repeat center / cover;
}

.six{
	background: url(https://image.tmdb.org/t/p/original/oLma4sWjqlXVr0E3jpaXQCytuG9.jpg) no-repeat center / cover;
}
<div class="scroll-container">
	<div class="container">
		<div class="wrapper first">
			<div class="bg one"></div>
		</div>

		<div class="wrapper">
			<div class="bg two"></div>
		</div>

		<div class="wrapper">
			<div class="bg three"></div>
		</div>

		<div class="wrapper">
			<div class="bg four"></div>
		</div>
		
		<div class="wrapper">
			<div class="bg five"></div>
		</div>
		
		<div class="wrapper">
			<div class="bg six"></div>
		</div>
	</div>
</div>

<div class="spacer"></div>
...