본문 바로가기

프로젝트/애플 웹사이트 클론

[ 애플 웹사이트 클론 ] 비디오에 스크롤 애니메이션 적용하기

비디오를 스크롤 애니메이션으로 보여주기 위해서는 세 가지의 방법이 존재한다.

 

 

  • 비디오의 길이를 이용해서, 스크롤된 비율에 따라 비디오의 해당 구간을 보여주는 방식
  • 비디오 프레임대로 이미지를 추출해서, 각 구간의 이미지를 보여주는 방식
  • 위와 비슷하게 이미지를 추출해서, 캔버스태그에 각 구간의 이미지를 그려 보여주는 방식

 

 

 

첫 번째의 비디오를 그대로 사용하는 방식은 이미지를 추출해서 사용하는 방식보다 부드럽지 못하고, 파일크기가 조금 더 커지기 때문에 패스했다.

	<video class="sample-video" src="../video/sample-low.mp4" muted></video>
	<!-- <video class="sample-video" src="../video/sample-high.mp4" muted></video> -->

	<script>
		const videoElem = document.querySelector('.sample-video');
		let progress;
		let currentFrame;
		function init() {
			document.body.classList.remove('before-load');

			window.addEventListener('scroll', function () {
				progress = pageYOffset / (document.body.offsetHeight - window.innerHeight);
				console.log(progress);
				if (progress < 0) progress = 0;
				if (progress > 1) progress = 1;

				videoElem.currentTime = videoElem.duration * progress;
			});
		}

		window.addEventListener('load', init);
	</script>

 

 

 

 

 

두 번째 방식은 확장성면에서 세 번째 방식보다 떨어진다고 생각했다. 지금은 하나의 이미지만을 화면에 보여주기 때문에, 큰 문제가 없을 것으로 보이나, 훗날 여러 개의 이미지를 겹쳐서 보여줘야하는 경우가 생길때 이미지태그는 여러 개의 이미지태그를 사용해야 하지만 캔버스태그는 하나의 판만 있으면 되기 때문에 성능면에서 유리할 것이다.

 

 

 

그래서 세 번째 방식인 캔버스태그에 이미지를 그려 보여주는 방식을 선택했다.

 

 

 

 

비디오를 애니메이션으로 보여주는 방식은 앞서 스타일값을 부여하는 것과 비슷한 방식이다.

하지만 추가되는 변수들이 있다.

	videoImageCount: 300,
	ImageSequence: [0, 299],

 

  • 비디오를 이미지로 추출한 이미지 개수
  • 이미지 순서 시작과 끝

 

  function setCanvasImages() {
    let imgElem;
    for (let i = 0; i < sceneInfo[0].values.videoImageCount; i++) {
      imgElem = new Image();
      imgElem.src = `./video/001/IMG_${6726 + i}.JPG`;
      sceneInfo[0].objs.videoImages.push(imgElem);
    }
    console.log(sceneInfo[0].objs.videoImages);
  }
  setCanvasImages();

 

 

그리고 new Image()를 통해, 이미지 객체를 생성하고 for문을 돌려 img객체의 src 경로를 동적으로 생성해준다.

그리고 새로운 배열에 그 이미지객체들을 넣어준다.

 

 

 

이미지 배열

 

위와 같이 300개의 이미지 객체들이 배열에 담기게 된다.

그리고 이 이미지들의 경로는 아까 for문을 통해 생성된 경로들이다. (ex. IMG_2011,IMG_2012,IMG_2013)

 

 

 

그렇다면 이제 스크롤된 비율에 따라서, 300개 중에서 특정 비율에 해당하는 구간의 이미지를 보여주면 된다!

 

 

 

 

이전 포스팅에서 만든 calcValues 함수를 사용하면 된다. (스크롤 비율에 따른 값 할당)

   let sequence = Math.round(
          calcValues(values.ImageSequence, currentYOffset)
        );

        objs.context.drawImage(objs.videoImages[sequence], 0, 0);
        objs.canvas.style.opacity = calcValues(
          values.canvas_opacity,
          currentYOffset
        );

 

 

sequence 값에는 스크롤된 비율이 10%면 300의 10%인 30번째가 찍힌다.

이 sequence값을 사용하여, 캔버스 태그의 context에 이미지를 그려주자.

 

여기서 주의해야할 점은, 스크롤된 비율이 소수점으로도 찍히기 때문에 소수점자리의 인덱스번호가 찍힌다.

따라서 Math.round 처리를 해주어야한다.

 

 

 

 

 

아, 그리고 새로고침을 하면 이미지가 아직 보이지 않는 데 처음 로드가 되었을 때 첫 번째 이미지를 넣어주는 함수를 추가해주자.

  window.addEventListener("load", () => {
    sceneInfo[0].objs.context.drawImage(sceneInfo[0].objs.videoImages[0], 0, 0);
    setLayout();
  });

 

 

 

 

 

 

 

 


 

 

아래와 같이, 스크롤에 따라서 이미지가 변한다. 무야호!

 

\