[TIL] Day61 #CSS_Animation #Canvas

Beanxxยท2022๋…„ 7์›” 26์ผ
0

TIL

๋ชฉ๋ก ๋ณด๊ธฐ
61/120
post-thumbnail

2022.07.22(Fri)

[TIL] Day61
[SEB FE] Day62

โ˜‘๏ธย CSS Animation

: ์—ฌ๋Ÿฌ ๊ฐœ์˜ CSS ์Šคํƒ€์ผ์„ ๋ถ€๋“œ๋Ÿฝ๊ฒŒ ์ „ํ™˜์‹œ์ผœ์คŒ

๐Ÿ“Žย @keyframes

: ์‹œ๊ฐ„ ์ˆœ์„œ๋Œ€๋กœ ์ •๋ฐ€ํ•˜๊ฒŒ ์งœ์—ฌ์ง„ ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

/* % ๋‹จ์œ„๋กœ ์‹œ๊ฐ„ ์ง„ํ–‰์— ๋”ฐ๋ฅธ ์ƒํƒœ ์ž‘์„ฑํ•ด์ฃผ๊ธฐ! */

@keyframes lotate { /* Animation Name */
	0% { /* = from */
		transform : rotate(0deg)
	}

	50% {
		transform : rotate(180deg)  /* 180๋„ ํšŒ์ „ */
	}

	100% { /* = to */
		transform : rotate(360deg)  /* 360๋„ ํšŒ์ „ */
	}

๐Ÿ“Žย Animation ์†์„ฑ

โœจย animation-name

: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ค‘๊ฐ„ ์ƒํƒœ๋ฅผ ์ง€์ •ํ•˜๋Š” ์ด๋ฆ„ (@keyframes ๋ธ”๋ก์— ์ž‘์„ฑ)

#logo {
	animation-name: lotate; // ์ ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ์š”์†Œ์— ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ด๋ฆ„ ์ž‘์„ฑํ•ด์ฃผ๊ธฐ
}

โœจย animation-duration

: ํ•œ cycle์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žฌ์ƒ๋  ์‹œ๊ฐ„ ์ง€์ •

  • ์‹œ๊ฐ„ ๋‹จ์œ„๋กœ ์ž‘์„ฑ (IF ์ž‘์„ฑ X โ†’ ๊ธฐ๋ณธ๊ฐ’ 0 โ†’ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ X)
#logo {
	animation-duration: 3s;  /* 3์ดˆ ๋™์•ˆ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ */
}

โœจย animation-delay

: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์‹œ์ž‘ ์ง€์—ฐ์‹œํ‚ฌ ์‹œ๊ฐ„ ์ง€์ •

#logo {
  animation-delay: 0s; /* ์ฆ‰์‹œ ์žฌ์ƒ */
	animation-delay: 3s; /* 3์ดˆ ๋™์•ˆ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ */
}
/* animation-name, duration, delay ์†์„ฑ์„ ์ฐจ๋ก€๋กœ ํ•œ๋ฒˆ์— ์ง€์ • ๊ฐ€๋Šฅ! */
#logo {
	animation: lotate 3s 3s;
}

โœจย animation-direction

: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ ๋ฐฉํ–ฅ ์ง€์ •

  • normal : default. ์žฌ์ƒ ๋๋‚˜๋ฉด ์ฒจ๋ถ€ํ„ฐ ๋‹ค์‹œ ์žฌ์ƒ
  • reverse : ์—ญ๋ฐฉํ–ฅ ์žฌ์ƒ
  • alternate : ์ˆœ๋ฐฉํ–ฅ๋ถ€ํ„ฐ ์—ญ๋ฐฉํ–ฅ์„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์žฌ์ƒ
  • alternate-reverse : ์—ญ๋ฐฉํ–ฅ๋ถ€ํ„ฐ ์ˆœ๋ฐฉํ–ฅ์„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์žฌ์ƒ
#logo {
	animation-direction: alternate;
}

โœจย animation-iteration-count

: ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ช‡ ๋ฒˆ ๋ฐ˜๋ณต๋ ์ง€ ์ง€์ •

  • default - 1
  • infinite - ๋ฌดํ•œ ๋ฐ˜๋ณต
  • ์†Œ์ˆ˜์  ์ž‘์„ฑ - ์žฌ์ƒ ๋„์ค‘ ์ฒ˜์Œ ์ƒํƒœ๋กœ ๋Œ์•„๊ฐ (3s * 0.6 = 1.8์ดˆ ์žฌ์ƒ ํ›„ ์ฒจ์œผ๋กœ ๋Œ์•„๊ฐ)
#logo {
	animation-iteraion-count: 3;  /* ์• ๋‹ˆ๋ฉ”์ด์…˜ 3๋ฒˆ ๋ฐ˜๋ณต */
}

โœจย animation-play-state

: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ ์ƒํƒœ (๋ฉˆ์ถ”๊ฑฐ๋‚˜ ๋‹ค์‹œ ์žฌ์ƒ)

  • default - running
  • ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ •์ง€ - pause
  • ๋ณดํ†ต ์ด๋ฒคํŠธ๋กœ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ ์ƒํƒœ ๋ณ€๊ฒฝ์‹œ ์‚ฌ์šฉ
    #logo {
    	animation-play-state: pause;
    }

โœจย animation-timing-function

: ์ค‘๊ฐ„ ์ƒํƒœ๋“ค์˜ ์ „ํ™˜์„ ์–ด๋– ํ•œ ์‹œ๊ฐ„ ๊ฐ„๊ฒฉ์œผ๋กœ ์ง„ํ–‰ํ• ์ง€ ์ง€์ • โ‡’ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง„ํ–‰ ์†๋„ ์„ค์ •

  • default - ease
  • linear
  • ease-in
  • ease-out
  • ease-in-out

โœจย animation-fill-mode

: ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ์žฌ์ƒ ์ „ & ํ›„ ์ƒํƒœ ์ง€์ •

  • none: default. ์žฌ์ƒ์ค‘์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์š”์†Œ ์Šคํƒ€์ผ ์œ ์ง€
  • forwards : ์žฌ์ƒ์ค‘์ด ์•„๋‹Œ ๊ฒฝ์šฐ ๋งˆ์ง€๋ง‰ ํ‚คํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ ์œ ์ง€
  • backwards : ์žฌ์ƒ์ค‘์ด ์•„๋‹Œ ๊ฒฝ์šฐ ์ฒซ ๋ฒˆ์งธ ํ‚คํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ ์œ ์ง€
  • both : ์žฌ์ƒ ์ „์—” ์ฒซ ๋ฒˆ์งธ ํ‚คํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ, ์žฌ์ƒ ํ›„์—” ๋งˆ์ง€๋ง‰ ํ‚คํ”„๋ ˆ์ž„ ์Šคํƒ€์ผ ์œ ์ง€


โ˜‘๏ธย Canvas

: HTML <canvas> ํƒœ๊ทธ์™€ JS๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์–‘ํ•œ ๊ทธ๋ž˜ํ”ฝ ์š”์†Œ ์ƒ์„ฑ ๊ฐ€๋Šฅ

<canvas id="canvas" width="500" height="500"></canvas>
// width, height ์†์„ฑ์€ ๋ฌด์กฐ๊ฑด pixel๋กœ ์ธ์‹!

// DOM์œผ๋กœ width, height ์„ค์ •ํ•ด์ฃผ๋Š” ๋ฐฉ๋ฒ•
canvas.width = 50vw;
canvas.heigth = 50vh;

// ํ™”๋ฉด ํฌ๊ธฐ ๋งž์ถฐ์„œ ์„ค์ •๋„ ๊ฐ€๋Šฅ
canvas.width = window.innerWidth;
canvas.heigth = window.innerHeight;

const canvas = document.querySelector('#canvas');

๐Ÿ“Žย Canvas๋กœ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ

โœจย ์ƒ‰์น ๋œ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ

// 1. ์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€๋ฅผ ์ƒ‰์น ํ•œ ์ƒ‰์ƒ ์„ค์ •
ctx.fillStyle = 'green';

// 2. ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
ctx.fillRext = (10, 10, 50, 50); // x์ขŒํ‘œ, y์ขŒํ‘œ, ๊ฐ€๋กœ๊ธธ์ด, ์„ธ๋กœ๊ธธ์ด

โœจย ์„ ์œผ๋กœ๋งŒ ๊ทธ๋ฆฌ๊ธฐ

// 1. ์„  ๊ตต๊ธฐ, ์„  ์ƒ‰์ƒ ์„ค์ •
ctx.lineWidth = 5;  // ์„  ๊ตต๊ธฐ
ctx.strokeStyle= 'black';  // ์„  ์ƒ‰์ƒ

// 2. ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ
ctx.strokeRect(10, 10, 50, 50); // x์ขŒํ‘œ, y์ขŒํ‘œ, ๊ฐ€๋กœ๊ธธ์ด, ์„ธ๋กœ๊ธธ์ด

โœจย ์‚ฌ๊ฐํ˜•์œผ๋กœ ์ง€์šฐ๊ธฐ

ctx.clearRect(20, 20, 30, 30); // x์ขŒํ‘œ, y์ขŒํ‘œ, ๊ฐ€๋กœ๊ธธ์ด, ์„ธ๋กœ๊ธธ์ด

๐Ÿ“Žย Canvas๋กœ ํด๋ฆญ์ด๋ฒคํŠธ ๋งŒ๋“ค๊ธฐ

โœจย ํด๋ฆญ์‹œ Canvas ์œ„์—์„œ์˜ ๋งˆ์šฐ์Šค ์œ„์น˜๋ฅผ ๊ตฌํ•˜๋ ค๋ฉด, ํ™”๋ฉด์ƒ ๋งˆ์šฐ์Šค ์œ„์น˜ - ์บ”๋ฒ„์Šค ์œ„์น˜

โžฐย ํ™”๋ฉด์ƒ ๋งˆ์šฐ์Šค ์œ„์น˜ ๊ตฌํ•˜๋Š” ์ด๋ฒคํŠธ ๊ฐ์ฒด ์†์„ฑ

  • X์ขŒํ‘œ: event.clientX
  • Y์ขŒํ‘œ: event.clientY

โžฐย ํ™”๋ฉด์ƒ ์บ”๋ฒ„์Šค ์œ„์น˜ ๊ตฌํ•˜๋Š” ์†์„ฑ

  • X์ขŒํ‘œ: ctx.canvas.offsetLeft (event.offsetX)
  • Y์ขŒํ‘œ: ctx.canvas.offsetTop (event.offsetY)
// ํด๋ฆญ์‹œ canvas ์œ„์— ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ

canvas.onclick = function (event) {
	const x = event.clientX - ctx.canvas.offsetLeft
	const y = event.clientY - ctx.canvas.offsetTop

	ctx.fillRect(x - 15, y - 15, 30, 30);
	// ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค 30px * 30px ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐ!!
	// x,y ๊ทธ๋Œ€๋กœ ์ „๋‹ฌ์‹œ ์ขŒํ‘œ๋ถ€ํ„ฐ ์‚ฌ๊ฐํ˜• ์‹œ์ž‘ -> ์–ด์ƒ‰ -> ํด๋ฆญ ์œ„์น˜๋ฅผ ์‚ฌ๊ฐํ˜• ์ •์ค‘์•™์ด ๋˜๋„๋ก!
	// => '์‚ฌ๊ฐํ˜• ํฌ๊ธฐ / 2' ๋งŒํผ ์ขŒํ‘œ์—์„œ ๋นผ์ฃผ๊ธฐ
	// ์ฆ‰, x-15, y-15 ์ „๋‹ฌ
}

๐Ÿ“Žย Chart.js ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

: ์—ฌ๋Ÿฌ ์ฐจํŠธ ์œ ํ˜•์„ ํ˜ผํ•ฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ ์งœ ์‹œ๊ฐ„, ๋กœ๊ทธ ๋“ฑ์— ์‰ฝ๊ฒŒ ํ‘œ์‹œ ๊ฐ€๋Šฅ + ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ œ๊ณต

$ npm install chart.js
<canvas id="popChart" width="500" height="500"></canvas>
// DOM์„ ํ†ตํ•ด ์ฐจํŠธ๋ฅผ ์ธ์Šคํ„ด์Šคํ™”!
let popCanvas = document.getElementById('popChart');
let popContext = document.getElementById('popChart').getContext('2d');

// ๋ชจ๋“  ํŒŒ๋ผ๋ฏธํ„ฐ๋“ค์„ Constructor์— ์ „๋‹ฌ

let barChart = new Chart(popCanvas, {
	type: 'bar',  // ์ฐจํŠธ ์œ ํ˜•
	data: {  // ์‹ค์ œ ๋ฐ์ดํ„ฐ
		labels: ['Korea', 'Japan', 'China', ...]
		datasets: [{
			label: 'Population',
			data: [234234, 234234, 2342356, ...],
			backgroundColor: [
				'rgba(255, 255, 255, 0.5)',
				...
			]
		}]
	}
});


โ˜‘๏ธย [pair] CSS Animation & Canvas ํ™œ์šฉ

์ €๋ฒˆ์— ๊ตฌํ˜„ํ–ˆ๋˜ ๋ฐ˜์‘ํ˜• ์›น ์‚ฌ์ดํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ CSS Animation๊ณผ Canvas ์ ์šฉํ•ด๋ณด๊ธฐ ๐Ÿ™Œ

  • Nav๋ฐ” ์ขŒ์ธก์— ๋กœ๊ณ  ์ด๋ฏธ์ง€๋ฅผ @keyframes๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํšŒ์ „์‹œ์ผฐ์œผ๋ฉฐ,
  • Main ๋ถ€๋ถ„์— ๋งˆ์šฐ์Šค๋ฅผ ํด๋ฆญํ•˜์—ฌ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๊ณ  ์ž๋™์œผ๋กœ ์‚ฌ๋ผ์ง€๋„๋ก ๊ตฌํ˜„ํ•ด๋ณด์•˜๋‹ค.
  • ๋ฉ”์ธ ํ™”๋ฉด ๋ถ€๋ถ„๊ณผ ๋ณ„๋„์˜ ์บ”๋ฒ„์Šค ์˜์—ญ์„ ๋”ฐ๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๋ฉ”์ธ ํ™”๋ฉด ์ „์ฒด ๋ถ€๋ถ„์„ ์บ”๋ฒ„์Šค์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•˜๋ ค๊ณ  ํ•œ ์ ์—์„œ ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ์‹œ๊ฐ„์ด ์˜ค๋ž˜๊ฑธ๋ ธ๋‹ค. ๊ฒฐ๊ตญ ํŽ˜์–ด๋‹˜์ด ํ•ด๊ฒฐํ•˜์…จ๋Š”๋ฐ ์ƒ๊ฐ๋ณด๋‹ค ์‰ฝ์ง€ ์•Š์•˜๋‹ค.,, ๋ญ”๊ฐ€ ๋” ๊ฐ„๋‹จํ•œ ๋ฐฉ๋ฒ•์ด ์žˆ์„ ๊ฒƒ ๊ฐ™๊ธด ํ•œ๋ฐ ๋” ๊ณต๋ถ€ํ•ด๋ด์•ผ ํ•  ๋ถ€๋ถ„!!

profile
FE developer

0๊ฐœ์˜ ๋Œ“๊ธ€