이미지 시퀀스

김종민·2023년 9월 22일
0

이미지 시퀀스

목록 보기
1/1
post-thumbnail


위와같이 애플에서 주로 보게 되는 이미지 시퀀스,
스크롤시 끊김이 없이 자연스럽게 이미지가 교체가 되어
시각적으로 편안한 이미지 시퀀스를 구현해준다.


📝코드 확인

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>

     <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/gsap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.10.4/ScrollTrigger.min.js"></script>
</head>
<body>
    
     <canvas id="canvas" class="canvas"></canvas>

     <script>
        // 이미지 시퀀스


    const canvas = document.querySelector('#canvas');
    const ctx = canvas.getContext('2d');

    canvas.width = 1694;
    canvas.height = 952;

    const frameCount = 60;

    const currentFrame = (idx) => {
        return `https://clingr.me/assets/images/media/landing/2.description/sequence/color/Seq01_color__${idx.toString().padStart(3, '0')}@xxl.webp`
    }; 
    
    const images = [];
    const card = {
        frame: 0,
    };


    //사전에 리소스를 로드한다

    for (let i = 0; i < frameCount; i++) {
        const img = new Image();
        img.src = currentFrame(i + 1);
        images.push(img);
    }

    gsap.to(card, {
        scrollTrigger: {
            trigger: '.canvas-area',
            scrub: 1,
            start: 'top top',
            end: 'bottom center',
        },
        frame: frameCount - 1,
        snap: 'frame',
        ease: 'none',
        onUpdate: render,
    });

    images[0].onload = render;

    function render() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.drawImage(images[card.frame], 0, 0);
    }

     </script>
</body>
</html>

✅코드 설명

  • canvas를 쓰지 않고 이미지를 교체하면 깜빡이며 끊김 현상이 나타남,
    canvas를 사용한다면 모닥불같은 효과나 3d효과도 구현이 가능하다!
    이 canvas는 2d라는걸 명시해준다. (3d면 3d라고 기입)
	const canvas = document.querySelector('#canvas');
    const ctx = canvas.getContext('2d');

  • canvas.width와 heigh는 영역의 크기를 기입한다.
   canvas.width = 1694;
    canvas.height = 952;

  • 처리를 할 리소스의 이미지 갯수를 적어준다.
   const frameCount = 60; //60개의 이미지

  • images라는 빈 배열 영역을 만들어줍니다.
	const images = [];

  • 반복문을 이미지 갯수만큼 돌리게 되고 위의 빈 images 배열에
    이미지들을 다 밀어 넣는다는 코드
 for (let i = 0; i < frameCount; i++) {
        const img = new Image();
        img.src = currentFrame(i + 1);
        images.👉 push(img);
    }

  • gsap을 사용해 트리거나 스크럽 같은 기본 설정을 해주는건 동일,
    여기서의 onUpdate는 gsap을 스크롤 할 때마다 계속 실행되게 하는 속성이며
    render라는 함수 코드에서 frame 마다마다에서 gsap이 짜주어서 하나하나씩 불러주는 것이다.
gsap.to(card, {
        scrollTrigger: {
            trigger: '.canvas-area',
            scrub: 1,
            start: 'top top',
            end: 'bottom center',
        },
      👉frame: frameCount - 1,
        snap: 'frame',
        ease: 'none',
      👉onUpdate: render,
    });
    
images[0].onload = render;

✅function render() {
	ctx.clearRect(0, 0, canvas.width, canvas.height);
	ctx.drawImage(images[card.frame], 0, 0);
}

  • 필요한 이미지를 받아올 사이트에 들어가 네트워크를 이용해 이미지를 찾은후
    미리보기 옆의 헤더를 클릭해 링크를 가져옵니다.


  • 그 해당 이미지의 처음 이미지의 링크를 가져와 return 값으로 지정해줍니다.
const currentFrame = (idx) => {
        return `https://clingr.me/assets/images/media/landing/2.description/sequence/color/Seq01_color__${idx.toString().padStart( 3, '0')}@xxl.webp`
    }; 

  • idxJavaScript 코드 조각을 사용하여 숫자 인덱스( )를 최소 길이가
    4자인 문자열로 변환하고 필요한 경우 0으로 채우는 것 같습니다
    idx.toString()숫자 인덱스를 문자열로 변환합니다. padStart(3, '0')문자열의 시작(왼쪽)부터 0으로 채워 최소 길이가 4자인지 확인합니다.
    예를 들어, idx7인 경우 최소 길이인 3자를 충족하기 위해 2개의 0이 채워졌기 때문에 결과는 "007" 문자열이 됩니다.
const currentFrame = (idx) => {
        return `https://clingr.me/assets/images/media/landing/2.description/sequence/color/Seq01_color__${idx.toString().👉 padStart( 3, '0')}@xxl.webp`
    }; 


코드 설명은 기본 지식을 습득하기 위함이고,
위의 코드를 복붙해서 사용하면 아주 간단하고 유용하게 사용할 수 있을것 같다.
이미지 링크와 이미지 갯수, 이미지 크기만 상황에 맞춰 수정해서 쓸 수 있다!
그리고 이미지 뿐만 아니라 비디오도 프레임으로 쪼개서 사용이 가능하다고 한다!

profile
웹 퍼블리셔의 코딩 일기

0개의 댓글