위와같이 애플에서 주로 보게 되는 이미지 시퀀스,
스크롤시 끊김이 없이 자연스럽게 이미지가 교체가 되어
시각적으로 편안한 이미지 시퀀스를 구현해준다.
<!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>
const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');
canvas.width = 1694;
canvas.height = 952;
const frameCount = 60; //60개의 이미지
const images = [];
for (let i = 0; i < frameCount; i++) {
const img = new Image();
img.src = currentFrame(i + 1);
images.👉 push(img);
}
onUpdate
는 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);
}
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 currentFrame = (idx) => {
return `https://clingr.me/assets/images/media/landing/2.description/sequence/color/Seq01_color__${idx.toString().👉 padStart( 3, '0')}@xxl.webp`
};
코드 설명은 기본 지식을 습득하기 위함이고,
위의 코드를 복붙해서 사용하면 아주 간단하고 유용하게 사용할 수 있을것 같다.
이미지 링크와 이미지 갯수, 이미지 크기만 상황에 맞춰 수정해서 쓸 수 있다!
그리고 이미지 뿐만 아니라 비디오도 프레임으로 쪼개서 사용이 가능하다고 한다!