๐ŸŽจ๐Ÿ”‘CSS , JS | SVG ํ™œ์šฉํ•ด ์Šคํฌ๋กค ์‹œ ๋ณ€ํ™” ์ฃผ๊ธฐ

์›์˜ยท2023๋…„ 5์›” 4์ผ
3

๋งŒ๋“ค์–ด๋ณด๊ธฐ๐Ÿคฉ

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

๐Ÿ”ŽSVG

  • ๋ฐฑํ„ฐ ๊ทธ๋ž˜ํ”ฝ์œผ๋กœ ์ด๋ฏธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฐฉ์‹
  • HTML ํƒœ๊ทธ์˜ ์ง‘ํ•ฉ์œผ๋กœ ์ด๋ฃจ์–ด์ ธ์„œ css์™€ javascript๋กœ ์กฐ์ž‘ ๊ฐ€๋Šฅ

์žฅ์ 

  • ์•„๋ฌด๋ฆฌ ํ™•๋Œ€๋ฅผ ํ•ด๋„ ์ด๋ฏธ์ง€๊ฐ€ ๊นจ์ง€์ง€ ์•Š์Œ

๋‹จ์ 

  • ์ฝ”๋“œ๋กœ ์ด๋ฃจ์–ด์ง„ ์ด๋ฏธ์ง€๋ผ ๋ณต์žกํ•œ ์ด๋ฏธ์ง€์ผ์ˆ˜๋ก ํŒŒ์ผ ์‚ฌ์ด์ฆˆ ์ปค์ง
  • ๋‹จ์ˆœํ•œ ๋ชจ์–‘์˜ ์•„์ด์ฝ˜, ๋กœ๊ณ , ๋„ํ˜• ๋“ฑ์„ ๊ตฌํ˜„ํ•  ๋•Œ ๋งŽ์ด ์‚ฌ์šฉ

๐ŸŽˆSVG ํ™œ์šฉํ•ด ์Šคํฌ๋กค ์‹œ ๋ณ€ํ™”ํ•˜๋Š” ํŽ˜์ด์ง€ ๋งŒ๋“ค๊ธฐ


๐Ÿ’กํ”ผ๊ทธ๋งˆ๋กœ SVG ํŒŒ์ผ ๋งŒ๋“ค๊ธฐ

  • ํ”ผ๊ทธ๋งˆ ํˆด๋กœ ์›ํ•˜๋Š” ๊ทธ๋ฆผ์„ ๊ทธ๋ฆฌ๊ณ  SVG ํŒŒ์ผ๋กœ export
    ์ œ๊ฐ€๊ทธ๋ฆฐ ์ด๋ฏธ์ง€ ใ…Žใ…Ž
    ์ฝ”๋“œ์— ์ ์šฉ

๐Ÿ’กSVG ํŒŒ์ผ์„ ๋‹ค๋ฃจ๋Š” CSS ์†์„ฑ

stroke-dasharray

  • ๋Œ€์‹œ(์ด๋ฏธ์ง€ ์„ )๊ธธ์ด์™€ ๊ณต๋ฐฑ๊ธธ์ด ์ง€์ •

์˜ˆ์‹œ

  • SVG ์ด๋ฏธ์ง€๋ฅผ 100px ๊ทธ๋ฆฌ๊ณ  20px ๊ณต๋ฐฑ์„ ์ฃผ๋Š” ํ˜•ํƒœ๋กœ ๋ฐ˜๋ณต
#line {
	stroke-dasharray: 100 20;
}


stroke-dashoffset

  • ์–ด๋Š๋งŒํผ ๋–จ์–ด์ง„ ๊ณณ์—์„œ ์ด๋ฏธ์ง€๋ฅผ ๊ทธ๋ฆด ์ง€ ์ง€์ •
  • stroke-dasharray ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ

์˜ˆ์‹œ

  • ์ „์ฒด ๊ธธ์ด์˜ 300px ๋งŒํผ ๋–จ์–ด์ง„ ๊ณณ์—์„œ ๊ทธ๋ฆฐ๋‹ค๊ณ  ์ง€์ •
#line {
	/* ์ „์ฒด ๊ธธ์ด 2856px๋กœ 2856px ๋งŒํผ ๋ณด์ด๊ณ  ๊ณต๋ฐฑ์ด๊ฒŒ ์„ค์ • */
	stroke-dasharray: 2856 2856;
    stroke-dashoffset: 300;
}

  • ์•„์˜ˆ ์•ˆ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ
#line {
	stroke-dasharray: 2856 2856;
    stroke-dashoffset: 2856;
}
  • ์ „์ฒด ๋‹ค ๋ณด์ด๊ฒŒ ํ•˜๋Š” ๊ฒฝ์šฐ
#line {
	stroke-dasharray: 2856 2856;
    stroke-dashoffset: 0;
}

๐Ÿ’ก์Šคํฌ๋กค์˜ ์œ„์น˜์— ๋”ฐ๋ผ SVG ๊ทธ๋ฆฌ๊ธฐ

  • ์Šคํฌ๋กค์ด ์ƒ๊ธฐ๊ฒŒ body์˜ height๋ฅผ 5000px๋กœ ์„ค์ •
  • getTotalLength() ๋ฅผ ์‚ฌ์šฉํ•ด SVG์˜ ๊ธธ์ด ๊ฐ€์ ธ์™€์„œ stroke-dasharray , stroke-dashoffset ์†์„ฑ ์„ค์ •
const line = document.querySelector('#line');
const lineLength = line.getTotalLength();

line.style.strokeDasharray = lineLength + ' ' + lineLength;
line.style.strokeDashoffset = lineLength;
  • scroll ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ์‹คํ–‰ํ•˜๋Š” ํ•จ์ˆ˜ scrollHandler( ) ์‹คํ–‰์‹œํ‚ด
  • scrollHandler( )
    ์Šคํฌ๋กค์ด ๊ฐ€์žฅ ์œ„์— ์œ„์น˜ํ•  ๋•Œ ์•„๋ฌด๊ฒƒ๋„ ๋ณด์ด์ง€ ์•Š๋‹ค๊ฐ€ ๋ฐ‘์œผ๋กœ ๋‚ด๋ฆฌ๋ฉด ๊ทธ๋ ค์ง
    ์Šคํฌ๋กค์ด ๊ฐ€์žฅ ๋ฐ‘์— ์œ„์น˜ํ•  ๋•Œ ๋‹ค ๊ทธ๋ ค์ง
  • ์Šคํฌ๋กค๋œ ์œ„์น˜๋ฅผ ์ „์ฒด ๋†’์ด์—์„œ %๋กœ ๊ตฌํ•˜๊ณ  stroke-dashoffset ์†์„ฑ๊ฐ’์„ ๋ฐ”๊ฟ”์ฃผ๋ฉด์„œ ๊ตฌํ˜„
window.addEventListener('scroll', scrollHandler)
function scrollHandler() {
  // ํ˜„์žฌ ์Šคํฌ๋กค๋œ ์œ„์น˜ ๊นŒ์ง€์˜ ๋†’์ด๊ฐ’
  const scrollTop = document.documentElement.scrollTop;
  // ์Šคํฌ๋กค๋  ์ˆ˜ ์žˆ๋Š” ์ „์ฒด ๋†’์ด๊ฐ’
  const scrollHeight = document.documentElement.scrollHeight;
  // ํ™”๋ฉด(๋ทฐํฌํŠธ)์˜ ๋†’์ด๊ฐ’
  const clientHeight = document.documentElement.clientHeight;

  // % ๊ตฌํ•˜๊ธฐ
  // ์ „์ฒด๊ฐ€ scrollHeight - clientHeight์ธ ์ด์œ 
  // ์Šคํฌ๋กคํ•  ์ˆ˜ ์žˆ๋Š” ์ „์ฒด ๋†’์ด๊ฐ’์—์„œ ํ˜„์žฌ ํ™”๋ฉด๋†’์ด๋งŒํผ ๋นผ ์ค˜์•ผ์ง€ ๊ฐ€์žฅ ๋ฐ‘์˜ ์Šคํฌ๋กค๊นŒ์ง€ ๊ฐ”์„ ๋•Œ 100%๊ฐ€ ๋จ
  const scrollPercentage = scrollTop / (scrollHeight - clientHeight)
  // ์Šคํฌ๋กค ์œ„์น˜์— ๋”ฐ๋ฅธ ๊ธธ์ด ๊ตฌํ•ด์คŒ
  const drawLength = lineLength * scrollPercentage

  // stroke-dashoffset ์†์„ฑ๊ฐ’์„ ๋ฐ”๊ฟ”์ฃผ๋ฉด์„œ ๊ตฌํ˜„
  // ์Šคํฌ๋กค ๊ฐ€์žฅ ์œ„์ผ ๋•Œ : ์›๋ž˜๊ธธ์ด - 0 (์•„๋ฌด๊ฒƒ๋„ ์•ˆ๋ณด์ž„)
  // ์Šคํฌ๋กค ๊ฐ€์žฅ ์•„๋ž˜์ผ ๋•Œ : ์›๋ž˜๊ธธ์ด - ์›๋ž˜๊ธธ์ด (์ „์ฒด ๋ณด์ž„)
  line.style.strokeDashoffset = lineLength - drawLength
}

๐Ÿ’ก๊ตฌํ˜„๊ฒฐ๊ณผ

profile
ํ™”์ดํŒ…~~^ใ…^/

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

๋ช…ํ•„

1๊ฐœ์˜ ๋‹ต๊ธ€