Я пытаюсь реализовать эффект плавной прокрутки, и у меня возникают проблемы при добавлении изображений высокого разрешения на страницу. Эффект плавный, пока я не добавлю изображения размером более 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>