๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
์‹œ๋„/๊ตญ๋น„์ง€์›

[D+50] canvas๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํฌ๋กค์— ๋ฐ˜์‘ํ•˜๋Š” ์ด๋ฏธ์ง€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉํ•˜๊ธฐ

by ๐Ÿ‡๋ฐ•๋ด‰๋ด‰๐Ÿ‡ 2022. 12. 1.

 

 

๊ตญ๋น„์ง€์› D+50

-  canvas๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํฌ๋กค์— ๋ฐ˜์‘ํ•˜๋Š” ์ด๋ฏธ์ง€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉํ•˜๊ธฐ  -

 


 

canvas๋ฅผ ์‚ฌ์šฉํ•ด ์Šคํฌ๋กค์— ๋ฐ˜์‘ํ•˜๋Š” ์ด๋ฏธ์ง€ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ ์šฉํ•˜๊ธฐ

canvas๋ฅผ ์‚ฌ์šฉํ•ด์„œ ์Šคํฌ๋กค์— ๋”ฐ๋ผ์„œ ์ด๋ฏธ์ง€๊ฐ€ ์›€์ง์ด๋Š” ํšจ๊ณผ๋ฅผ ์ ์šฉํ•ด ๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

์ผ๋‹จ 3๊ฐ€์ง€ ๋‹จ๊ณ„๋ณ„๋กœ ์ˆœ์ฐจ์ ์œผ๋กœ ์ง„ํ–‰ํ•ด ๋ณด๋„๋ก ํ•˜์ž.

0 > ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ค€๋น„ํ•˜๊ธฐ
1 > html์— canvas ํƒœ๊ทธ ์ถ”๊ฐ€
2 > canvas ํƒœ๊ทธ์— ๋Œ€ํ•œ CSS ์„ค์ •
3 > canvas ์ปจํŠธ๋กค ๊ธฐ๋Šฅ๋“ค์„ ์ถ”๊ฐ€

 

0 > ์ด๋ฏธ์ง€ ํŒŒ์ผ ์ค€๋น„ํ•˜๊ธฐ

๋‚˜๋Š” ์Šคํฌ๋กค์„ ํ• ๋•Œ๋งˆ๋‹ค ์‚ฌ๊ณผ๊ฐ€ ๋Œ์•„๊ฐ€๋Š” ๊ฒƒ๊ฐ™์€ ํšจ๊ณผ๋ฅผ ๋ณด์ด๊ธฐ์œ„ํ•ด ๋™์˜์ƒ์„ ํ”„๋ ˆ์ž„๋ณ„๋กœ ์ชผ๊ฐœ์„œ ์ด๋ฏธ์ง€๋กœ ์ €์žฅํ•ด imageํด๋”์•ˆ์— ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

 

1 > html์— canvas ํƒœ๊ทธ ์ถ”๊ฐ€

<canvas id="main-canvas" width="1920" height="1080"></canvas>

 

 

๋จผ์ € body์•ˆ์— canvasํƒœ๊ทธ๋ฅผ ๋„ฃ์–ด์ฃผ์—ˆ์œผ๋ฉฐ id์„ค์ • ๋ฐ ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ด ์ฃผ์—ˆ๋‹ค.

 

2 > canvas ํƒœ๊ทธ์— ๋Œ€ํ•œ CSS ์„ค์ •

#main-canvas {
	border: 1px solid black;
	position: fixed;
}

body {
	margin: 0;
	padding: 0;
	border: 0;
	height: 4000px;
}

ํƒœ๊ทธ์—๋Œ€ํ•œ ์Šคํƒ€์ผ์„ ์ ์šฉํ•ด์ฃผ์—ˆ์œผ๋ฉฐ ์ด๋•Œ ์Šคํฌ๋กค์„ ์›€์ง์ผ๋•Œ๋งˆ๋‹ค ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ ์šฉํ•  ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— body์˜ ๋†’์ด๋ฅผ ์ž„์˜๋กœ ์ง€์ •ํ•ด ์ฃผ์—ˆ๋‹ค.

 

3 > canvas ์ปจํŠธ๋กค ๊ธฐ๋Šฅ๋“ค ์ถ”๊ฐ€

• STEP01 > ๋ Œ๋”๋ง ์ปจํ…์ŠคํŠธ ์„ค์ •

๋‹จ์ˆœํžˆ canvas ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๊ฐ€์ง€๊ณ  ์˜จ๋‹ค๊ณ  ํ•ด์„œ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜๋Š” ์—†๋‹ค.

๋“œ๋กœ์ž‰์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋งŽ์€ ์„ค์ •๋“ค์„ ํ•ด์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ (์ขŒํ‘œ, ์ƒ‰, ํฌ๊ธฐ, ๋ฉ”๋ชจ๋ฆฌ์„ค์ • ๋“ฑ๋“ฑ...) ์ด๋Ÿฌํ•œ ์„ค์ •๋“ค์ด ๋˜์–ด์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋Ÿฌํ•œ ์„ค์ •๊ฐ’๋“ค์˜ ์ง‘ํ•ฉ์„ graphic context๋ผ๊ณ  ํ•˜๋Š”๋ฐ gc๋Š” ์ผ์ผํžˆ ์„ค์ •ํ•ด์ค„ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ๊ฐ’๋“ค๋กœ ์„ค์ •๋˜์–ด ์žˆ๋Š” ๋„๊ตฌ๋ฅผ ๊ฐ€์ ธ์™€์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

const mainCanvas = document.querySelector('#main-canvas');

const gc = mainCanvas.getContext('2d');

 

getContext() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋ Œ๋”๋ง ์ปจํ…์ŠคํŠธ์™€ ๊ทธ๋ฆฌ๊ธฐ ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ ๋กœ ๋‚ด๊ฐ€ ๋‹ค๋ฃฐ ์ด๋ฏธ์ง€๋Š” 2D ๊ทธ๋ž˜ํ”ฝ์ด๋ฏ€๋กœ 2D์™€ ๊ด€๋ จ๋œ ๋“œ๋กœ์ž‰ ์ปจํ…์ŠคํŠธ๋ฅผ ์„ค์ •ํ•ด ์ฃผ์—ˆ๋‹ค.

 

• STEP02 > canvas ์ด๋ฏธ์ง€ ๋ฐฐ์—ด ์…‹ํŒ…

ํ˜„์žฌ ์ด๋ฏธ์ง€๋Š” imageํด๋” ์•ˆ์— ์žˆ๋Š” ๊ฒƒ์ผ๋ฟ ๋‚ด๊ฐ€ ๋”ฐ๋กœ ๋ถˆ๋Ÿฌ์˜ค๊ฑฐ๋‚˜ ํ•˜์ง€๋Š” ์•Š์€ ์ƒํƒœ์ด๋‹ค.

ํ™”๋ฉด์— ์ด๋ฏธ์ง€๋ฅผ ์˜ฌ๋ฆฌ๊ธฐ ์œ„ํ•ด ๊ฐ๊ฐ์˜ ์ด๋ฏธ์ง€๋“ค์—๋Œ€ํ•œ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ๋งŒ๋“ค๊ณ  ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด์ค€ ๋‹ค์Œ์— ๋ฐฐ์—ด์— ๋„ฃ์–ด์ฃผ๋„๋ก ํ•œ๋‹ค.

let imgElement;
let canvasImages = [];	// ๊ฐ๊ฐ์˜ imgElement๋ฅผ ๋„ฃ์–ด์ค„ ๋ฐฐ์—ด

for(let i = 0; i < 500; i++)
{
    imgElement = new Image();
    imgElement.src = `./image/apple_${i}.png`;
    
    // ๋ฐฐ์—ด์•ˆ์— ๋‹จ์ˆœํžˆ ๊ฒฝ๋กœ๊ฐ’์„ ๋„ฃ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ด๋ฏธ์ง€๋ฅผ ๋””๊ณ ํŒ…ํ•ด์„œ ๊ฐ€์ง€๊ณ ์žˆ๋Š” ๊ฒƒ
    canvasImages.push(imgElement);
}

 

 

๋‚˜๋Š” ์ด๋ฏธ์ง€๋ฅผ 500์žฅ์„ ์ค€๋น„ํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ ์ด๋ฏธ์ง€๋“ค์—๋Œ€ํ•œ  image ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด canvasImages๋ฐฐ์—ด์•ˆ์— ๋ฐ˜๋ณต๋ฌธ์„ ์‚ฌ์šฉํ•ด์„œ ๋„ฃ์–ด์ฃผ์—ˆ๋‹ค.

์ด๋•Œ ๊ธฐ์–ตํ•ด์•ผํ•  ๊ฒƒ์€ ๋ฐฐ์—ด์•ˆ์— ๋‹จ์ˆœํžˆ ๊ฒฝ๋กœ๊ฐ’์„ ๋„ฃ์–ด์ค€ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋žœ๋”๋งํ•  ์ค€๋น„๊ฐ€ ๋˜์–ด์žˆ๋Š” imgํƒœ๊ทธ๋“ค์„ ๋„ฃ์—ˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ด์•ผํ•œ๋‹ค.

 

• STEP03 > ์Šคํฌ๋กค์œ„์น˜๊ฐ’์— ๋”ฐ๋ฅธ CSS๊ฐ’ ๊ณ„์‚ฐ ํ•จ์ˆ˜ ์ƒ์„ฑ

๋น„์œจ์—๋”ฐ๋ฅธ CSS๊ฐ’ ๊ณ„์‚ฐ ํ•จ์ˆ˜๋Š” ์ด์ „ ๊ฒŒ์‹œ๋ฌผ์—๋„ ์˜ฌ๋ ค๋†จ๊ธฐ์— ์„ค๋ช…์€ ์ƒ๋žตํ•˜๋„๋ก ํ•œ๋‹ค.

 

let yOffset = 0;	

const mainCanvas = document.querySelector('#main-canvas');
         
const calcValue = function(values){
	let result = 0;
	let rate = 0;
	let height = document.body.scrollHeight - window.innerHeight;
            
	rate = yOffset / height;
            
	result = (rate * (values[1] - values[0])) + values[0];

	return result;
}

 

 

• STEP04 > ์ด๋ฒคํŠธ ์ ์šฉ

๊ฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋˜์—ˆ์„๋•Œ์— ๋Œ€ํ•œ ๊ธฐ๋Šฅ์ด ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ์„ค์ •ํ•ด์ฃผ๋ฉฐ, ์ฒ˜์Œ ๋กœ๋“œ๋˜์—ˆ์„๋•Œ์—๋Š” ์ด๋ฏธ์ง€์˜ ์ฒซํ™”๋ฉด์ด ์…‹ํŒ…๋˜๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.

 

์ดํ›„ ์Šคํฌ๋กค์ด ๋ฐœ์ƒ๋ ๋•Œ๋งˆ๋‹ค scrollY๊ฐ’์— ๋Œ€ํ•œ CSS๊ฐ’์„ ๊ณ„์‚ฐํ•ด์„œ ์Šคํฌ๋กค ์œ„์น˜์— ๋”ฐ๋ฅธ ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋ ค๋‚ผ ์ˆ˜ ์žˆ๋„๋ก ํ•ด์ฃผ์—ˆ๋‹ค.

// load๋˜์—ˆ๋‹ค๋Š” ๊ฒƒ์€ ์ด์ „ ์—˜๋ฆฌ๋จผํŠธ๋“ค ํฌํ•จ ๋ชจ๋“  ์—˜๋ฆฌ๋จผํŠธ๋“ค์ด ๋‹ค ๋Œ์•˜๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.
imgElement.addEventListener('load', () => {

	// ํ™”๋ฉด์— ๊ทธ๋ ค๋ผ (์ด๋ฏธ์ง€๊ฐ์ฒด, ์œ„์น˜)
	gc.drawImage(canvasImages[0], 0, 0);

});

window.addEventListener("scroll", () => {
	let imageIndex = 0;

	yOffset = window.scrollY;
        
	imageIndex = Math.floor(calcValue([0, 499]));

	gc.drawImage(canvasImages[imageIndex], 0, 0);
});

 

 

4 > ๊ฒฐ๊ณผํ™”๋ฉด

 

 

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€