JSFiddle - React, Tailwind, and code Playground

by Yunus Gaziev

HTML

<div id="viewport_wrapper">
  <div id="viewport" class="viewport"></div>
</div>

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

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

Задача организации, в особенности же сложившаяся структура организации позволяет оценить значение существенных финансовых и административных условий. Разнообразный и богатый опыт постоянный количественный рост и сфера нашей активности требуют определения и уточнения новых предложений. Повседневная практика показывает, что укрепление и развитие структуры представляет собой интересный эксперимент проверки системы обучения кадров, соответствует насущным потребностям. Задача организации, в особенности же постоянный количественный рост и сфера нашей активности позволяет выполнять важные задания по разработке систем массового участия. Идейные соображения высшего порядка, а также постоянное информационно-пропагандистское обеспечение нашей...

CSS

.viewport {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  
  display: flex;
  align-items: center;
  justify-content: center;
}

.frame {
  position: absolute;
  width: 30%;
  height: auto;
  vertical-align: top;
  
  top: 50%;
  left: 50%;
  
  transform: translate3d(-50%, -50%, 0);
  
  opacity: 0;
}
.frame:first-child {
  opacity: 1;
}

JavaScript

const body     = document.querySelector('body');
const wrapper  = document.getElementById('viewport_wrapper');
const viewport = document.getElementById('viewport');
const images   = [];
const count    = 45; // frames
const step     = 20; // px
const path     = count * step + window.innerHeight;

let wrapper_height = wrapper.getBoundingClientRect().height;

for	(let i = 1; i <= count; i++) {
	let img = new Image();
  
  img.src = `https://craft-flue.ru/local/templates/Craft/assets/img/scroll/${i}.png`;
  
  img.classList.add('frame');
  
  viewport.appendChild(img);
  
  images.push(img);
}

wrapper.style['padding-top'] = path + 'px';

document.addEventListener('scroll', () => {
	let frame = Math.ceil(window.scrollY / step);
	if (frame <= count) {
    viewport.style.position = 'fixed';
    viewport.style.top = 0;
    
    images.forEach((img) => {
    	img.style.opacity = 0;
    });
    
    let index = frame-1 > 0 ? frame-1 : 0;
    
  	images[index].style.opacity = 1;
  } else {
  	
  	viewport.style.position = 'absolute';
    viewport.style.top = wrapper_height + window.innerHeight + 'px';
  }
});