
์์ฒ๋ผ ํ ์คํธ์ path๋ฅผ ๋ฐ์ ์ ๋๋ฉ์ด์ ํจ๊ณผ๋ฅผ ์ฃผ๋ ์์ ๋ฅผ ๋ง๋ค์ด๋ดค๋ค.
ํ๋กํ ํ์ดํ ํด๋ก ์ ์ฌ์ฉํ๊ณ ์๋ figma๋ก ๊ธฐ๋ณธ์ด ๋๋ SVG๋ฅผ ๋ง๋ค๊ณ , ๊ฐ๋จํ ์๋ฐ์คํฌ๋ฆฝํธ์ CSS๋ก ์ ๋๋ฉ์ด์ ์ ๋ง๋ค์๋ค.
SVG ํ๊ทธ ์์ฑ

figma๋ก ์๋ฌด draft๋ ์ด์ด์ ์บ๋ฒ์ค๋ฅผ ๋ง๋ ๋ค์, T ์์ด์ฝ์ ๋๋ฌ ํ ์คํธ๋ฅผ ์์ฑํ๋ค. figma์์ ํ๊ธ์ ๋ฐ์นจ์ ํ์ดํํ ๋ ๋ฌธ์ ๊ฐ ์์ด์, ํ๊ตญ์ด ํ ์คํธ๋ก SVG ์์ค๋ฅผ ์ค๋นํด์ผ ํ๋ค๋ฉด, ํฌํ ์ต ๋ฑ ๋ค๋ฅธ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๋ซ๋ค.

์ด๋ ๊ฒ ์๋ฌด ํ ์คํธ ๋ฐ์ค๊ฐ ์์ฑ๋๊ณ , ํ์ฌ๋ Path๋ฅผ ๋ฐ์ง ์์์ผ๋ฏ๋ก ํ๋์ ํ ํฌ๋ฆฌ๊ฐ ํ ์คํธ ๋ฐ์ค ์ ์ฒด์ ๊ฑธ์ณ ์๋ ๊ฒ์ ๋ณผ ์ ์๋ค.

์ฌ๊ธฐ์ ์ฐํด๋ฆญ -> outline stroke๋ฅผ ๋๋ฌ์ฃผ๊ณ ,

์ด ์ํ์์ ์ค๋ฅธ์ชฝ์ Design ํจ๋์ Stroke ๋ Fill ์ ์ฌ๋ฌ ์ค์ ๊ฐ์ ์ฃผ์ด ๋์์ธํ๋ค. ๋๋ Fill์ ์ญ์ ํด์ฃผ๊ณ , Stroke์ width๋ฅผ 7๋ก, ๋ฐํ ์์ ํฐ์์ผ๋ก ๋ฐ๊ฟ์ฃผ์๋ค.

์ค์ ์ ๋ง์น๊ณ ๋๋ฉด, code editor์ ๋ถ๋ฌ์ ๋ถ์ฌ๋ฃ์ด์ฃผ๋ฉด ์๋์ฒ๋ผ <svg> ํ๊ทธ ์์ <mask> .. <rect> .. <path> ์์ผ๋ก ์ ์์ค๊ฐ ๋ณต์ฌ๋ ๊ฒ์ ์ ์ ์๋ค. ๋ฌผ๋ก ์ด๋ค ํํ๋ฅผ ๋ง๋๋๋์ ๋ฐ๋ผ ํ๊ทธ๋ ์์ดํ ์ ์๋ค.

SVG Path Animation ๋ง๋ค๊ธฐ

body {
margin: 0;
padding: 0;
background-color: #e7dcc2;
}
#logo {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
ํ์์ ๊ธ์๋ฅผ ๋ฐํ์ผ๋ก ํ๊ณ ์์ผ๋ฏ๋ก, ์์ฒ๋ผ ๊ธฐ๋ณธ CSS๋ฅผ ์์ฑํด์ฃผ๊ณ , ์ด์ getTotalLength()๋ฅผ ์ด์ฉํด ๊ฐ Path์ ์ ์ฒด ๊ธธ์ด๋ฅผ ๊ฐ์ง๊ณ ์ฌ ์ฐจ๋ก์ด๋ค.
์ฐ์ ์ ์ฒด์ ์ธ HTML ํํ๋ ์๋์ ๊ฐ๋ค.
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>ํ๊ธ ํ ์คํธ ์ ๋๋ฉ์ด์ </title> | |
<link rel="stylesheet" href="hangeul_text.css"> | |
</head> | |
<body> | |
<svg id="logo" width="357" height="422" viewBox="0 0 357 422" fill="none" xmlns="http://www.w3.org/2000/svg"> | |
<mask id="path-1-outside-1" maskUnits="userSpaceOnUse" x="0.199951" y="0.399994" width="357" height="422" | |
fill="black"> | |
<rect fill="white" x="0.199951" y="0.399994" width="357" height="422" /> | |
<path | |
d="M111 27.4H66.2V5.39999H49.8V27.4H5.19995V40.6H111V27.4ZM30.8 83.8C30.8 71.4 41.8 63.4 58 63.4C74.2 63.4 85.3999 71.4 85.3999 83.8C85.3999 96.4 74.2 104.4 58 104.4C41.8 104.4 30.8 96.4 30.8 83.8ZM101 83.8C101 63.8 83.4 50.6 58 50.6C32.6 50.6 15.2 63.8 15.2 83.8C15.2 104 32.6 117.2 58 117.2C83.4 117.2 101 104 101 83.8ZM48.5999 129.4H32.2V180.8H151.8V167.4H48.5999V129.4ZM143.8 64.6V5.39999H127.4V140H143.8V78.4H170.2V64.6H143.8Z" /> | |
<path | |
d="M224.584 148.6H330.984V103.4H207.784V116.4H314.584V136.2H208.384V182.6H335.384V169.6H224.584V148.6ZM326.384 72.2C330.384 52 330.384 36.6 330.384 24.4V13H209.384V26.2H314.184C314.184 38 313.984 52.4 309.984 72.2H188.584V85.4H351.384V72.2H326.384Z" /> | |
<path | |
d="M111 261.4H66.2V239.4H49.8V261.4H5.19995V274.6H111V261.4ZM30.8 317.8C30.8 305.4 41.8 297.4 58 297.4C74.2 297.4 85.3999 305.4 85.3999 317.8C85.3999 330.4 74.2 338.4 58 338.4C41.8 338.4 30.8 330.4 30.8 317.8ZM101 317.8C101 297.8 83.4 284.6 58 284.6C32.6 284.6 15.2 297.8 15.2 317.8C15.2 338 32.6 351.2 58 351.2C83.4 351.2 101 338 101 317.8ZM48.5999 363.4H32.2V414.8H151.8V401.4H48.5999V363.4ZM143.8 298.6V239.4H127.4V374H143.8V312.4H170.2V298.6H143.8Z" /> | |
<path | |
d="M224.584 382.6H330.984V337.4H207.784V350.4H314.584V370.2H208.384V416.6H335.384V403.6H224.584V382.6ZM326.384 306.2C330.384 286 330.384 270.6 330.384 258.4V247H209.384V260.2H314.184C314.184 272 313.984 286.4 309.984 306.2H188.584V319.4H351.384V306.2H326.384Z" /> | |
</mask> | |
<path class="myPath" | |
d="M111 27.4H66.2V5.39999H49.8V27.4H5.19995V40.6H111V27.4ZM30.8 83.8C30.8 71.4 41.8 63.4 58 63.4C74.2 63.4 85.3999 71.4 85.3999 83.8C85.3999 96.4 74.2 104.4 58 104.4C41.8 104.4 30.8 96.4 30.8 83.8ZM101 83.8C101 63.8 83.4 50.6 58 50.6C32.6 50.6 15.2 63.8 15.2 83.8C15.2 104 32.6 117.2 58 117.2C83.4 117.2 101 104 101 83.8ZM48.5999 129.4H32.2V180.8H151.8V167.4H48.5999V129.4ZM143.8 64.6V5.39999H127.4V140H143.8V78.4H170.2V64.6H143.8Z" | |
stroke="white" stroke-width="10" mask="url(#path-1-outside-1)" /> | |
<path class="myPath" | |
d="M224.584 148.6H330.984V103.4H207.784V116.4H314.584V136.2H208.384V182.6H335.384V169.6H224.584V148.6ZM326.384 72.2C330.384 52 330.384 36.6 330.384 24.4V13H209.384V26.2H314.184C314.184 38 313.984 52.4 309.984 72.2H188.584V85.4H351.384V72.2H326.384Z" | |
stroke="white" stroke-width="10" mask="url(#path-1-outside-1)" /> | |
<path class="myPath" | |
d="M111 261.4H66.2V239.4H49.8V261.4H5.19995V274.6H111V261.4ZM30.8 317.8C30.8 305.4 41.8 297.4 58 297.4C74.2 297.4 85.3999 305.4 85.3999 317.8C85.3999 330.4 74.2 338.4 58 338.4C41.8 338.4 30.8 330.4 30.8 317.8ZM101 317.8C101 297.8 83.4 284.6 58 284.6C32.6 284.6 15.2 297.8 15.2 317.8C15.2 338 32.6 351.2 58 351.2C83.4 351.2 101 338 101 317.8ZM48.5999 363.4H32.2V414.8H151.8V401.4H48.5999V363.4ZM143.8 298.6V239.4H127.4V374H143.8V312.4H170.2V298.6H143.8Z" | |
stroke="white" stroke-width="10" mask="url(#path-1-outside-1)" /> | |
<path class="myPath" | |
d="M224.584 382.6H330.984V337.4H207.784V350.4H314.584V370.2H208.384V416.6H335.384V403.6H224.584V382.6ZM326.384 306.2C330.384 286 330.384 270.6 330.384 258.4V247H209.384V260.2H314.184C314.184 272 313.984 286.4 309.984 306.2H188.584V319.4H351.384V306.2H326.384Z" | |
stroke="white" stroke-width="10" mask="url(#path-1-outside-1)" /> | |
</svg> | |
<script src="hangeul_text.js"></script> | |
</body> | |
</html> |
๊ตฌ์กฐ๋ฅผ ๋ณด๋ฉด <svg> ์์ <mask>, <rect>, <path> ์์ธ๋ฐ, ์ ๋๋ฉ์ด์ ์ ๋์์ํฌ path๋ <mask> ํ๊ทธ๊ฐ ๋๋๊ณ ๋ ๋ค์์ ์ด 4๊ฐ์ <path> ํ๊ทธ์ด๋ค. ์ด๋ค ํ ์คํธ๋ฅผ ์ฌ์ฉํ๋๋์ ๋ฐ๋ผ ์ด <path> ํ๊ทธ์ ์๋ ๋ฌ๋ผ์ง๋ค.
๊ฐ๊ฐ์ path ํ๊ทธ์๋ myPath๋ผ๋ ํด๋์ค๋ฅผ ์จ์ฃผ์๊ณ , <svg>์๋ logo ์์ด๋๋ฅผ ๋ถ์ฌํ๋ค.
const logo = document.querySelectorAll("#logo .myPath");
for(let i = 0; i < logo.length; i++) {
console.log(`${i+1}๋ฒ์งธ path์ ์ด ๊ธธ์ด ${logo[i].getTotalLength()}`);
}
float someElement.getTotalLength();
path์ ์ด ๊ธธ์ด๋ฅผ ํ์ธํ๊ธฐ ์ํด querySelectorAll๋ก ์ ์ฒด node๋ฅผ ๊ฐ์ง๊ณ ์๋ค. for๋ฌธ์ ๋๋ ค i๋ฒ์งธ ๋ ธ๋์ ์ ์ฒด path ๊ธธ์ด๋ฅผ ๊ฐ์ง๊ณ ์ค๋ getTotalLength() ๋ฉ์๋๋ฅผ ์ด๋ค. ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ด์ด๋ณด๋ฉด ์๋์ฒ๋ผ ์ ์ฒด ๊ธธ์ด๊ฐ ๋ฐํ๋์ด ์จ๋ค.

๋ค์ CSS ํ์ผ๋ก ๋์์, ๊ฐ๊ฐ์ ๊ธ์์ ์ด๋ป๊ฒ stroke ๋ณํ๋ฅผ ์ค ์ ์๋์ง ์์๋ณด๊ธฐ ์ํด nth-child ๋๋ nth-of-type์ ์จ #logo ์๋์ .myPath๋ฅผ ํ๋ ํ๋ ์ ํํด์ค๋ค.
nth-of-type()๊ณผ nth-child() ๋น๊ต
/* nth-of-type์ ์ธ ๊ฒฝ์ฐ */
#logo .myPath:nth-of-type(1) {
}
#logo path:nth-of-type(2) {
}
#logo .myPath:nth-of-type(3) {
}
#logo .myPath:nth-of-type(4) {
}
/* nth-child๋ฅผ ์ธ ๊ฒฝ์ฐ */
#logo path:nth-child(2) {
}
#logo path:nth-child(3) {
}
#logo path:nth-child(4) {
}
#logo path:nth-child(5) {
}
ํ์ฌ html ํ๊ทธ์ <svg> ๋ด๋ถ๋ฅผ ๋ณด๋ฉด <mask> ํ๊ทธ ๊ทธ๋ฆฌ๊ณ 4๊ฐ์ <path> ํ๊ทธ๋ก ๊ตฌ์ฑ๋์ด ์๋ค. nth-child๋ ์๋ก ๋๋ฑํ ์์น์ ํ๊ทธ๋ค ๋ด์์์ ์์๋ฅผ ์ง๊ธฐ ๋๋ฌธ์, #logo์ path์ nth-child()๋ฅผ ์ธ ๊ฒฝ์ฐ mask ํ๊ทธ๋ฅผ ์ผ ๋ค์ 2๋ฒ์งธ์ ๋ฑ์ฅํ๋ฏ๋ก ์ซ์๊ฐ 2๋ถํฐ ์์ํ๊ฒ ๋๋ค.
nth-of-type์ ์ธ ๊ฒฝ์ฐ์๋ ๊ฐ์ ์ข ๋ฅ์ ํ์ ๋ด์์ ์์์ ์์๋ฅผ ์นด์ดํธ ํ๊ธฐ ๋๋ฌธ์, .myPath๋ผ๋ ํด๋์ค๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฌถ๋ , path๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ฌถ๋ #logo ํ์์ 4๊ฐ์ <path>๋ง์ ์๊ฐํด ๊ณ์ฐํ๋ฉด ๋๋ค.
stroke-dasharray, stroke-dashoffset

#logo path:nth-of-type(1) { stroke-dasharray: 50px; }
์ ํ๊ทธ๋ฅผ ์ ์ฉํ์ ๋๋ ์ผ์ชฝ์ ๋ชจ์ต๊ณผ ๊ฐ๋ค.
์ด๋ค element์๋ ์ ์ฉ๊ฐ๋ฅํ ์์ฑ์ด์ง๋ง, ์ค์ ๋ก ํจ๊ณผ๋ฅผ ๋ณผ ์ ์๋ ํ๊ทธ๋ ์๋ ์ด ๋ ๊ฐ๋ก ์ ํ์ ์ด๋ค.
<path>, <ellipse>, <line>, <polygon>, <rect>, <text>, <textPath>, <tref>, <tspan>, <altGlyph>, <circle>
dash๋ผ๋ ์ด๋ฆ์ด ๋ค์ด๊ฐ๋ ๊ทธ๋๋ก, ์ ์ ์ ๋ง๋ค์ด์ฃผ๋ ์์ฑ์ด๋ค. ์ด ์์ฑ๊ณผ ๊ฐ์ด stroke-dashoffset ์์ฑ์ด ์ฐ์ด๋๋ฐ, ์ด ์์ฑ์ ์ด๋์์๋ถํฐ ์์ํ ์ง๋ฅผ ์ ํด์ค๋ค.
Animation
์ํ๋ ์ ๋๋ฉ์ด์ ์ ๊ธ์๊ฐ ์ ํ ์๋ค๊ฐ ์์ํ path๊ฐ ๊ทธ๋ ค์ง๋ ํํ๋ก, ์ต์ข ์ ์ผ๋ก๋ ์ ์ฒด๊ฐ ๋ค ๋ณด์ด๋๋ก ํ ๊ฒ์ด๋ค. stroke-dasharray๊ฐ ํด๋น ์์์ ์ ์ฒด ๊ธธ์ด์ ๋์ผํ๋ค๋ฉด, ์ ์ ์ ํ๋๋ ์๋ ์ํ์ด๋ค. ๋ง์ผ offset๋ ๋์ผํ๊ฒ ๊ฐ์ ๊ฐ์ด๋ผ๋ฉด

์ด๋ ๊ฒ ์ฌ๋ผ์ ธ ์๋ ํํ๊ฐ ๋ ๊ฒ์ด๋ค. keyframe ์ ๋๋ฉ์ด์ ์ ํตํด stroke-dashoffset์ 0์ผ๋ก ์ฃผ๋๋ก ํด๋ณธ๋ค.
๊ทธ๋ฆฌ๊ณ ๊ฐ path์
animation: line-anime 5s ease-out forwards; ๋ฅผ ํ ์ค ์ถ๊ฐํ๋ค.
์์๋๋ก ํคํ๋ ์์ ์ด๋ฆ, ์ ๋๋ฉ์ด์ ์์ ์๊ฐ, ์ ๋๋ฉ์ด์ timing function, animation-fill-mode ์ด๋ค. forwards๋ ์ ๋๋ฉ์ด์ ์ด ํคํ๋ ์์ 100%์ ๋๋ฌํ์ ๋ ๋ง์ง๋ง ํคํ๋ ์์ ์ ์งํ๋ค.
๋ง์ง๋ง์ผ๋ก path๋ฅผ ๊ทธ๋ฆฌ๋ ์ ๋๋ฉ์ด์ ์ด ์ข ๋ฃ๋๋ฉด ์ ์ฒด ๊ธ์๋ฅผ ํ์์์ผ๋ก ๊ทธ๋ฆฌ๋ ์ ๋๋ฉ์ด์ ์ ๋ฃ๊ณ ์ข ๋ฃํ๊ณ ์ ํ ๋๋, <svg> ํ๊ทธ์ <mask> ํ๊ทธ์ ๋์์ ์ ๋๋ฉ์ด์ ์ ์ ์ฉํด์ผ ์ ๋๋ก ๋์ํ๋ค. #path-1-outside-1์ <mask> ํ๊ทธ์ ์๋์ผ๋ก ์ค์ ๋์ด ์๋ id ๊ฐ์ด๋ค.
#logo,
#path-1-outside-1 {
animation: fill-out 1s ease-out forwards 2s;
}
@keyframes fill-out {
from {
fill: transparent;
}
to {
fill: white;
}
}


๊ฐ์ธ์ ์ผ๋ก๋ ์์๋ก ์ฌ์ฉํ ํ์์ ๊ฒฝ์ฐ๊ฐ ๋ ์ ๋๋ฉ์ด์ ์์ง์์ด ๋ค์ํด์ ์ ํฉํด ๋ณด์ธ๋ค.
๋ค์์๋ JavaScript๊ฐ ์๋ SCSS๋ก๋ง ์ ๋๋ฉ์ด์ ์ ๊ตฌํํ๋ ๋ฐฉ๋ฒ๋ ์ฐพ์๋๋ฉด ์ข์ ๊ฒ ๊ฐ๋ค.
'๐ฉโ๐ป > Web' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
SOP(Same-Origin-Policy), CORS(Cross-Origin-Resource-Sharing) (0) | 2021.05.10 |
---|