[CSS] ๐Ÿ“€keyframes, ๐Ÿ—žCanvas ์‚ฌ์šฉ๋ฒ•

TATAยท2023๋…„ 3์›” 17์ผ
0

CSS

๋ชฉ๋ก ๋ณด๊ธฐ
2/3
post-thumbnail

(๋ฏธ๋””์–ด ์ฟผ๋ฆฌ์™€ ํ‚คํ”„๋ ˆ์ž„์œผ๋กœ ๋งŒ๋“  ๊ฐ„๋‹จํ•œ ํŽ˜์ด์ง€)

โ–ท @keyframes

๊ธฐ๋ณธ ํ‹€

@keyframes ์• ๋‹ˆ๋ฉ”์ด์…˜์ด๋ฆ„ {
	0% {            /* from ์ด๋ผ๊ณ  ์ž‘์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.*/
		CSS์†์„ฑ : ์†์„ฑ๊ฐ’; 
	}

	50% {           /* ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ง„ํ–‰๋„์— ๋”ฐ๋ฅธ ์Šคํƒ€์ผ์„ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. */
                    /* ํ•„์š”ํ•˜๋‹ค๋ฉด 1๋ถ€ํ„ฐ 99๊นŒ์ง€๋„, ์†Œ์ˆ˜์ ๊นŒ์ง€๋„ ๋ชจ๋‘ ์ž‘์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.*/
		CSS์†์„ฑ : ์†์„ฑ๊ฐ’;
	}

	100% {          /* to ๋ผ๊ณ  ์ž‘์„ฑํ•ด๋„ ๋ฉ๋‹ˆ๋‹ค.*/
		CSS์†์„ฑ : ์†์„ฑ๊ฐ’;
	}
}

ํšŒ์ „ํ•˜๋Š” ํ‚คํ”„๋ ˆ์ž„ ์˜ˆ์‹œ

@keyframes lotate {
	0% {
		transform : rotate(0deg)
	}

	50% {
		transform : rotate(180deg)
	}

	100% {
		transform : rotate(360deg)
	}
}
/* ์‹œ์ž‘ ์‹œ์ ์—์„  0๋„, 50% ์‹œ์ ์—์„  180๋„, ์™„๋ฃŒ ์‹œ์ ์—์„  360๋„ ํšŒ์ „์‹œํ‚ค๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์ž…๋‹ˆ๋‹ค. */

-----
/* ๋งŒ๋“  ํ‚คํ”„๋ ˆ์ž„ ์• ๋‹ˆ๋งค์ด์…˜ ์ ์šฉ */
.logo {
  animation: lotate 3s;
}

์•„๋ž˜์—์„œ ์œ„๋กœ ์˜ฌ๋ผ์˜ค๋Š” ํ‚คํ”„๋ ˆ์ž„ ์˜ˆ์‹œ

@keyframes fadeIn {
  from {
    opacity: 1;
    transform: translateY(60px); /* ์ ์šฉํ•  ๊ณณ์— ๋งž๊ฒŒ  translateY์„ ์กฐ์ ˆํ•ด์ฃผ๋ฉด ๋จ */
  }
  to {
    opacity: 3;
    transform: none;
  }
}
  
-----
์• ๋‹ˆ๋งค์ด์…˜ ์ ์šฉํ•  ๊ณณ {
  animation: fadeIn 0.35s ease-out;
}

bounce ํ‚คํ”„๋ ˆ์ž„

@keyframes bounce {
  from {
    transform: translateY(0);
  }
  to {
    transform: translateY(-5px);
  }
}

animation: bounce 500ms infinite alternate ease-in

animation-play-state

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

.cd-box {
  width: 562px;
  border-radius: 50%;
  animation: rotate 7.2s linear infinite;
  animation-play-state: ${({ isPlaying }) => (isPlaying ? 'running' : 'paused')};
}

๐Ÿ“€ ์• ๋‹ˆ๋งค์ด์…˜ ์†์„ฑ

animation: ๋„์–ด์“ฐ๊ธฐ๋กœ ์ญ‰ ๋‚˜์—ดํ•˜๋ฉด ์•„๋ž˜์˜ ์†์„ฑ๋“ค์„ ํ•œ ๋ฒˆ์— ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

animation-name: ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ์ค‘๊ฐ„ ์ƒํƒœ๋ฅผ ์ง€์ •ํ•˜๋Š” ์ด๋ฆ„. @keyframes ๋ธ”๋ก์— ์ž‘์„ฑ
animation-duration : ํ•œ ์‹ธ์ดํด์˜ ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žฌ์ƒ๋  ์‹œ๊ฐ„ ์ง€์ •
animation-delay: ์• ๋‹ˆ๋ฉ”์ด์…˜์˜ ์‹œ์ž‘์„ ์ง€์—ฐ์‹œํ‚ฌ ์‹œ๊ฐ„ ์ง€์ •
animation-direction: ์• ๋‹ˆ๋ฉ”์ด์…˜ ์žฌ์ƒ ๋ฐฉํ–ฅ์„ ์ง€์ •
animation-iteration-count: ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ช‡ ๋ฒˆ ๋ฐ˜๋ณต๋ ์ง€ ์ง€์ •
animation-play-state: ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์žฌ์ƒ ์ƒํƒœ. ๋ฉˆ์ถ”๊ฑฐ๋‚˜ ๋‹ค์‹œ ์žฌ์ƒ ์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ
animation-timing-function: ์ค‘๊ฐ„ ์ƒํƒœ๋“ค์˜ ์ „ํ™˜์„ ์–ด๋–ค ์‹œ๊ฐ„๊ฐ„๊ฒฉ์œผ๋กœ ์ง„ํ–‰ํ• ์ง€ ์ง€์ •
animation-fill-mode: ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ์žฌ์ƒ ์ „ ํ›„์˜ ์ƒํƒœ ์ง€์ •


๐Ÿ“€ ์‚ฌ์šฉ ์˜ˆ์‹œ

โ–ท duration / delay

.logo {
	animation : lotate 3s 3s ;
}

/* ์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. */
.logo {
	animation-name : lotate;
	animation-duration : 3s;
	animation-delay : 3s;
}

โ–ท direction

.logo {
	animation : lotate 3s reverse ;
}

/* ์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. */
.logo {
	animation-name : lotate;
	animation-duration : 3s;
	animation-direction : alternate;
}

/*
* normal : ๊ธฐ๋ณธ ๊ฐ’. ์žฌ์ƒ์ด ๋๋‚˜๋ฉด ์ฒ˜์Œ๋ถ€ํ„ฐ ๋‹ค์‹œ ์žฌ์ƒํ•ฉ๋‹ˆ๋‹ค.
* reverse : ์—ญ๋ฐฉํ–ฅ์œผ๋กœ ์žฌ์ƒํ•ฉ๋‹ˆ๋‹ค.
* alternate : ์ˆœ๋ฐฉํ–ฅ๋ถ€ํ„ฐ ์—ญ๋ฐฉํ–ฅ์„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์žฌ์ƒํ•ฉ๋‹ˆ๋‹ค.
* alternate-reverse : ์—ญ๋ฐฉํ–ฅ๋ถ€ํ„ฐ ์ˆœ๋ฐฉํ–ฅ์„ ๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉฐ ์žฌ์ƒํ•ฉ๋‹ˆ๋‹ค.
*/

โ–ท iteration-count

.logo {
	animation : lotate 3s infinite ;
    /* ์• ๋‹ˆ๋ฉ”์ด์…˜์ด ๋ฌดํ•œ ๋ฐ˜๋ณต ๋ฉ๋‹ˆ๋‹ค. */
}

.logo {
	animation-name : lotate;
	animation-duration : 3s;
	animation-iteration-count : 3 ;
    /* ์• ๋‹ˆ๋ฉ”์ด์…˜์ด 3๋ฒˆ ๋ฐ˜๋ณต ๋ฉ๋‹ˆ๋‹ค. */
}

โ–ท play-state

.logo {
	animation : lotate 3s pause ;
}

/* ์œ„ ์ฝ”๋“œ๋Š” ์•„๋ž˜์™€ ๊ฐ™๋‹ค. */
.logo {
	animation-name : lotate;
	animation-duration : 3s;
	animation-play-state : pause ;
}


/*
* paused : ์ •์ง€
* running : ์›€์ง์ž„
* inherit : ์ƒ์†
*/

โ–ท fill-mode

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

๐Ÿ“€ styled-component์˜ keyfames

import styled, { keyframes } from 'styled-components';

const fadein = keyframes`
  from {
    opacity: 0;
  }
  to {
    opacity: 1;
  }
`

const fadeout = keyframes`
  from {
    opacity: 1;
  }
  to {
    opacity: 0;
  }
`

-----
/* ์‚ฌ์šฉํ•  ์ปดํฌ๋„ŒํŠธ์— ์ ์šฉ. props๋กœ ํ™œ์šฉ ๊ฐ€๋Šฅ */
animation: 0.35s;
animation-name: ${(props) => props.fadeIn ? fadein : fadeout}

โ–ท Canvas

๐Ÿ—ž ย ๋ฐฉ๋ฒ• 1ย 

์บ”๋ฒ„์Šค๋Š” canvas ์—˜๋ฆฌ๋จผํŠธ๋ฅผ DOM์œผ๋กœ ์กฐ์ž‘ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘์„ฑ๋œ๋‹ค.

<!-- id๋กœ ์ž‘์„ฑํ•ด์ฃผ๋Š” ๊ฒƒ์ด ์ข‹๋‹ค. -->
<!-- ๋„ˆ๋น„์™€ ๋†’์ด๋ฅผ ์„ค์ •ํ•ด ์ค€๋‹ค. -->
<!-- ํฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ด์ฃผ์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ 300px 150px๋กœ ์ƒ์„ฑ๋จ -->
<canvas id="canvas" width="500" height="500">
	์บ”๋ฒ„์Šค๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š” ์บ”๋ฒ„์Šค ๋Œ€์‹  ํƒœ๊ทธ ์‚ฌ์ด ๋‚ด์šฉ์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
</canvas>

-----
<!-- vw, vh๋ฅผ ์ „๋‹ฌํ–ˆ์ง€๋งŒ 50ํ”ฝ์…€ 40ํ”ฝ์…€๋กœ ์„ค์ •๋จ -->
<!-- ํ”ฝ์…€ ๋‹จ์œ„๋กœ๋งŒ ๋ช…์‹œํ•ด์•ผ ์ธ์‹ํ•˜๋„๋ก ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ -->
<canvas id="canvas" vw="500" vh="500"></canvas>

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋กœ ์—˜๋ฆฌ๋จผํŠธ๋ฅผ ์„ ํƒํ•ด์ค€๋‹ค.

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

๐Ÿ—ž ย ๋ฐฉ๋ฒ• 2ย 

DOM์œผ๋กœ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
์ด ๊ฒฝ์šฐ์—” ์œ ๋™์ ์ธ ๊ฐ’๋„ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜์—ฌ
์บ”๋ฒ„์Šค์˜ ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •๋˜์–ด ์žˆ์ง€ ์•Š์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•˜๊ธฐ ์ข‹๋‹ค.

// ํ™”๋ฉด ํฌ๊ธฐ์— ๋งž์ถฐ์„œ ์„ค์ •ํ•ด์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

// ํ™”๋ฉด ํฌ๊ธฐ๋ฅผ ๊ฐ€์ ธ์™€ ๊ทธ์— ๋น„๋ก€ํ•˜์—ฌ ์„ค์ •ํ•ด์ค„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
canvas.width = window.innerWidth * 0.5;
canvas.height = window.innerHeight * 0.4;

// DOM์œผ๋กœ ์„ค์ •ํ•  ์‹œ, ํ”ฝ์…€ ๋‹จ์œ„๊ฐ€ ์•„๋‹Œ vw, vh๋กœ ๋‹จ์œ„๊ฐ’์„ ์ง€์ •ํ•ด๋„ ์„ค์ •์ด ๋ฉ๋‹ˆ๋‹ค. 
// ์ฃผ์˜ํ•ด์•ผ ํ•  ์ ์€ style ์†์„ฑ์„ ์ด์šฉํ•˜์—ฌ ํฌ๊ธฐ์— ๋ณ€ํ™”๋ฅผ ์ฃผ๋Š” ๊ฒฝ์šฐ๋Š” ํ”ฝ์…€์˜ ํฌ๊ธฐ๊นŒ์ง€ ํ•ด๋‹น ๋‹จ์œ„์— ๋น„๋ก€ํ•ด ํ™•๋Œ€ํ•˜๋Š” ๊ฐœ๋…์ด๋ฏ€๋กœ, 
// ํŠน์ •ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์•„๋‹ˆ๋ฉด ์‚ฌ์šฉ์„ ์ž์ œํ•ฉ๋‹ˆ๋‹ค.
canvas.style.width = "50vw";
canvas.style.height = "40vh";

๐Ÿ—ž ย ์บ”๋ฒ„์Šค๋กœ ์‚ฌ๊ฐํ˜• ๊ทธ๋ฆฌ๊ธฐย 

fillStyle: ์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€ ์ƒ‰์ƒ
fillRect: ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ ค์คŒ
lineWidth: ์„ ์˜ ๊ตต๊ธฐ
strokeStyle: ์„ ์˜ ์ƒ‰์ƒ
strokeRect: ์„ ์œผ๋กœ ๋œ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ ค์คŒ
clearRect: ์ง€์šธ ๋ฒ”์œ„

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

// ์‚ฌ๊ฐํ˜• ๋‚ด๋ถ€๋ฅผ ์ƒ‰์น ํ•  ์ƒ‰์ƒ์„ ์„ค์ •
ctx.fillStyle = 'blue'
// ์ „๋‹ฌ ์ธ์ž๋Š” ์ˆœ์„œ๋Œ€๋กœ x์ขŒํ‘œ, y์ขŒํ‘œ, ๊ฐ€๋กœ๊ธธ์ด, ์„ธ๋กœ๊ธธ์ด ์ด๋‹ค.
ctx.fillRect = (10, 10, 100, 50)

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

// ์„ ์˜ ๊ตต๊ธฐ๋ฅผ ์„ค์ •
ctx.lineWidth = 5;
// ์„ ์˜ ์ƒ‰์ƒ์„ ์„ค์ •
ctx.strokeStyle = "black";

// ์ „๋‹ฌ ์ธ์ž๋Š” ์ˆœ์„œ๋Œ€๋กœ x์ขŒํ‘œ, y์ขŒํ‘œ, ๊ฐ€๋กœ๊ธธ์ด, ์„ธ๋กœ๊ธธ์ด ์ด๋‹ค.
ctx.strokeRect(10, 10, 100, 50)

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

// ์ „๋‹ฌ ์ธ์ž๋Š” ์—ญ์‹œ ๋™์ผํ•ฉ๋‹ˆ๋‹ค.
// ๊ทธ๋ ค๋†“์€ ์‚ฌ๊ฐํ˜• ๊ฐ€์šด๋ฐ ๋ถ€๋ถ„์„ ์ง€์›Œ๋ณด์„ธ์š”.
ctx.clearRect( 20, 20, 80, 30)

๐Ÿ—ž ย ์บ”๋ฒ„์Šค๋กœ ํด๋ฆญ์ด๋ฒคํŠธ ๋งŒ๋“ค๊ธฐย 

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

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

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

-------

ํ™”๋ฉด์ƒ ์บ”๋ฒ„์Šค์˜ ์œ„์น˜๋ฅผ ๊ตฌํ•˜๋Š” ์†์„ฑ

X์ขŒํ‘œ : ctx.canvas.offsetLeft
Y์ขŒํ‘œ : ctx.canvas.offsetTop

ํ˜น์€ event.offsetX, event.offsetY๋กœ ๋ฐ”๋กœ ๊ตฌํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ตœ์ข… ๊ตฌํ˜„ ์ฝ”๋“œ

html

<canvas id="canvas" width="200" height="150"></canvas>

javascript

const canvas = document.querySelector("#canvas");
const ctx = canvas.getContext("2d");
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;

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);
		// ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค 30ํ”ฝ์…€*30ํ”ฝ์…€ ํฌ๊ธฐ์˜ ์‚ฌ๊ฐํ˜•์„ ๊ทธ๋ฆฌ๋„๋ก ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.
		// ์ด ๋•Œ, x, y๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•˜๋ฉด ํ•ด๋‹น ์ขŒํ‘œ๋ถ€ํ„ฐ ์‚ฌ๊ฐํ˜•์ด ์‹œ์ž‘๋˜์–ด ์–ด์ƒ‰ํ•œ ๋Š๋‚Œ์„ ์ค๋‹ˆ๋‹ค.
		// ํด๋ฆญํ•œ ์œ„์น˜๋ฅผ ์‚ฌ๊ฐํ˜•์˜ ์ •์ค‘์•™์ด ๋˜๊ฒŒ ํ•˜๋ ค๋ฉด ์‚ฌ๊ฐํ˜•ํฌ๊ธฐ/2 ํ•œ ๋งŒํผ ์ขŒํ‘œ์—์„œ ๋นผ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
		// ๋”ฐ๋ผ์„œ x - 15, y - 15 ๋ฅผ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
}

โ–ท Chart.js

Canvas๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ์œ ์šฉํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ด๋‹ค.
์—ฌ๋Ÿฌ ์ข…๋ฅ˜์˜ ์ฐจํŠธ๋ฅผ ๋งŒ๋“œ๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ฌ๋Ÿฌ ์ฐจํŠธ ์œ ํ˜•์„ ํ˜ผํ•ฉํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ๋‚ ์งœ ์‹œ๊ฐ„,
๋กœ๊ทธ ๋˜๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ์ฒ™๋„์— ์‰ฝ๊ฒŒ ํ‘œ์‹œํ•  ์ˆ˜ ์žˆ๋‹ค.
๋˜ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜ ์ƒ‰์ƒ์„ ์—…๋ฐ์ดํŠธํ•  ๋•Œ
์ฆ‰์‹œ ์ ์šฉํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์• ๋‹ˆ๋ฉ”์ด์…˜์„ ์ œ๊ณตํ•œ๋‹ค.


๐Ÿ“Š ย ์„ค์น˜ย 

โ–ท ์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ

<!-- header ์•ˆ์— script ํƒœ๊ทธ๋ฅผ ์—ด๊ณ  CDN ์ฃผ์†Œ๋ฅผ ๋„ฃ์–ด์ค€๋‹ค. -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js" ></script>

โ–ท ๋ฆฌ์•กํŠธ

// ๋ฆฌ์•กํŠธ์—์„  ์ง์ ‘ ์„ค์น˜ํ•ด์•ผ ํ•จ
npm install react-chartjs-2 chart.js
// ๊ฐ€์ ธ์˜ค๊ธฐ
import Chart from "chart.js";

๐Ÿ“Š ย ์ฐจํŠธ ๋งŒ๋“ค๊ธฐย 

โ–ท ์ˆœ์ˆ˜ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ

html

<canvas id="myChart" width="600" height="400"></canvas>

javascript

let myCanvas = document.getElementById("myChart").getContext("2d");


...

const labels = [
        'January',
        'February',
        'March',
        'April',
        'May',
        'June',
    ];

const data = {
    labels: labels,
    datasets: [{
    label: 'My First dataset',
    // โ†“ ๋ง‰๋Œ€ ๋ณ„๋กœ ์ƒˆ์ƒ์„ ๋‹ค๋ฅด๊ฒŒ ํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ(๊ธฐ๋ณธ๊ฐ’: rgba(0,0,0,0.1))
    backgroundColor: 'rgb(255, 99, 132)',
    borderColor: 'rgb(255, 99, 132)',
    data: [0, 10, 5, 2, 20, 30, 45],
  }]
};

const config = {
    type: 'line',
    data: data // ์‹ค์ œ ๋ฐ์ดํ„ฐ๋“ค์„ ๋‹ด๊ณ  ์žˆ์Œ
};

//์ด ๋ถ€๋ถ„์ด chart constructor ์ด๋‹ค.
const myChart = new Chart(
    myCanvas,
    config
);

/*
* ํƒ€์ž… ์ข…๋ฅ˜
* - line
* - bar
* - radar
* - polarArea
* - pie
* - doughnut
* - bubble
*/

โ–ท ๋ฆฌ์•กํŠธ

//canvas๋ฅผ ์‚ฌ์šฉํ•ด useRef๋ฅผ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•˜์—ฌ chart.js@2 ๋ฒ„์ „์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
const ExmapleChart = ({ data }) => {
  //useRef ์‚ฌ์šฉ.
  const chartRef = useRef(null);
  //chart๋ฅผ ์ €์žฅํ•ด๋‘˜ state๋ฅผ ๋งˆ๋ จ.
  const [myChart, setMyChart] = useState(null);

  //์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋กœ๋”ฉ๋˜๋ฉด์„œ ๋™์‹œ์— ๋– ์•ผ ํ•˜๋ฏ€๋กœ useEffect๋ฅผ ์‚ฌ์šฉ.
  useEffect(() => {
    //chartRef๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ๋™์ž‘ํ•˜์ง€ X
    if (!chartRef) return;

    //์ฐจํŠธ๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์œ„ํ•œ ๊ฐ์ฒด ์ƒ์„ฑ
    const ctx = chartRef.current.getContext("2d");

    //์‹ค์ œ ์ฐจํŠธ๋ฅผ ๊ทธ๋ฆฌ๋Š” ๊ณณ
    const myChart = new Chart(ctx, {
      type: "bar",
      data: {
        labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
        datasets: [
          {
            label: "# of Votes",
            data: data,
            backgroundColor: [
              "rgba(255, 99, 132, 0.2)",
              "rgba(54, 162, 235, 0.2)",
              "rgba(255, 206, 86, 0.2)",
              "rgba(75, 192, 192, 0.2)",
              "rgba(153, 102, 255, 0.2)",
              "rgba(255, 159, 64, 0.2)",
            ],
            borderColor: [
              "rgba(255, 99, 132, 1)",
              "rgba(54, 162, 235, 1)",
              "rgba(255, 206, 86, 1)",
              "rgba(75, 192, 192, 1)",
              "rgba(153, 102, 255, 1)",
              "rgba(255, 159, 64, 1)",
            ],
            borderWidth: 1,
          },
        ],
      },
    });

    //์ฐจํŠธ ์ƒํƒœ๋ฅผ ์ €์žฅ
    setMyChart(myChart);
  }, []);

  //data์™€ ์ฐจํŠธ๊ฐ€ ๋ฐ”๋€” ๋•Œ๋งˆ๋‹ค ๋ Œ๋”๋ง
  useEffect(() => {
    if (!myChart) return;

    myChart.data.datasets[0].data = data;
    myChart.update();
  }, [data, myChart]);

  return <canvas ref={chartRef} id="myChart" width="400" height="400" />;
};



๐Ÿ–ผ๋ฏธ๋””์–ด ์ฟผ๋ฆฌ / ๐ŸŽž๋ฆฌํ”Œ๋กœ์šฐ, ๋ฆฌํŽ˜์ธํŠธ ์ตœ์ ํ™” ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
๐Ÿ‘‰ text-animation codepen
๐Ÿ‘‰ css animation ์‚ฌ์ดํŠธ ๋ชจ์Œ
๐Ÿ‘‰ 3schools์˜ Canvas Reference

profile
๐ŸŒฟ https://www.tatahyeonv.com

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