본문 바로가기
CSS/애니메이션

CSS 애니메이션 : SVG 만들기와 SVG 애니메이션

by 코딩 척척학사 2022. 9. 7.
728x90

애니메이션 만들기

svg를 만들고, svg를 이용한 애니메이션을 만들어봅니다! 간단한 형태의 svg 이미지는 코딩으로도 만들 수 있으니, 잘 알아두었다가 활용해봅시다!

SVG란?

스케일러블 벡터 그래픽스(Scalable Vector Graphics, SVG)는 2차원 벡터 그래픽을 표현하기 위한 XML 기반의 파일 형식으로, 1999년 W3C(World Wide Web Consortium)의 주도하에 개발된 오픈 표준의 벡터 그래픽 파일 형식이다. SVG 형식의 이미지와 그 작동은 XML 텍스트 파일들로 정의 되어 검색화·목록화·스크립트화가 가능하며 필요하다면 압축도 가능하다.

> SVG의 특징 알아보기

  • 인터넷 익스플로러9 버전 이상부터 지원됩니다.
  • XML을 이용하여 라인, 곡선, 기하학적인 그래픽 표현이 가능합니다.
  • 벡터 방식이기 때문에 확대하거나 축소가 가능합니다.
  • DOM 단위로 컨트롤이 가능하지만 문서 복잡도가 증가되면 렌더링이 느려집니다.

> SVG 만들기

SVG와 관련 태그를 이용하여 코딩을 통해 SVG 이미지를 만들 수 있습니다.

종류 예시 설명
사각형(rect) rect 태그를 이용해 사각형을 만듭니다.
<div class="svgBox svg1">
    <svg>
        <rect fill="#F48FB1" width="100" height="100" x="30" y="30" />
    </svg>
    <svg>
        <rect fill="#F48FB1" width="100" height="100" x="30" y="30" stroke="#880E4F" stroke-width="5" />
    </svg>
    <svg>
        <rect fill="#F48FB1" width="100" height="100" x="30" y="30" rx="20" ry="20" />
    </svg>
    <svg>
        <rect fill="#F48FB1" width="100" height="100" x="30" y="30" rx="20" ry="20" stroke="#880E4F" stroke-width="5" />
    </svg>
    <svg>
        <rect fill="#F48FB1" width="100" height="100" x="30" y="30" rx="40" ry="40" />
    </svg>
    <svg>
        <rect fill="#F48FB1" width="100" height="100" x="30" y="30" rx="60" ry="60" stroke="#880E4F" stroke-width="5" />
    </svg>
</div>
원형
(circle, ellipse)
ellipse 혹은 circle 태그를 이용해 원형을 만듭니다.
<div class="svgBox svg1">
    <svg>
        <circle fill="#F48FB1" r="60" cx="80" cy="80" />
    </svg>
    <svg>
        <circle fill="#F48FB1" r="60" cx="80" cy="80" stroke="#880E4F" stroke-width="5" />
    </svg>
    <svg>
        <ellipse fill="#F48FB1" rx="60" ry="40" cx="80" cy="80" />
    </svg>
    <svg>
        <ellipse fill="#F48FB1" rx="60" ry="40" cx="80" cy="80" stroke="#880E4F" stroke-width="5" />
    </svg>
    <svg>
        <ellipse fill="#F48FB1" rx="40" ry="60" cx="80" cy="80" />
    </svg>
    <svg>
        <ellipse fill="#F48FB1" rx="40" ry="60" cx="80" cy="80" stroke="#880E4F" stroke-width="5" />
    </svg>
</div>
다각형(polygon) polygon 태그를 이용해 다각형을 만듭니다. 직접 만들기도 가능하나, 복잡하기 때문에 프로그램을 활용합시다.
<div class="svgBox svg3">
    <svg>
        <polygon points="136,141 10,101 108,12" fill="#F48FB1" />
    </svg>
    <svg>
        <polygon points="121,131 56,140 15,89 39,27 104,18 145,70" fill="#F48FB1"/>
    </svg>
    <svg>
        <polygon points="115,134 71,144 30,124 12,82 26,39 64,14 108,20 139,53 142,98" fill="#F48FB1" />
    </svg>
    <svg>
        <polygon points="133,129 87,115 50,144 49,96 9,70 54,54 67,8 96,47 144,45 116,84" fill="#F48FB1" />
    </svg>
    <svg>
        <polygon points="128,130 94,111 88,149 73,114 45,141 53,104 15,110 44,84 10,66 48,62 30,28 64,47 70,9 85,45 113,17 105,55 143,49 114,75 148,92 110,96" fill="#F48FB1" />
    </svg>
    <svg>
        <polygon points="80,8.15 81.84,70.37 106.02,13.02 85.26,71.69 128.53,26.96 87.98,74.17 144.49,48.08 89.62,77.46
151.73,73.55 89.96,81.12 149.29,99.91 88.95,84.65 137.49,123.61 86.74,87.59 117.93,141.45 83.61,89.52 93.24,151.01 80,90.2
66.76,151.01 76.39,89.52 42.07,141.45 73.26,87.59 22.51,123.61 71.05,84.65 10.71,99.91 70.04,81.12 8.27,73.55 70.38,77.46
15.51,48.08 72.02,74.17 31.47,26.96 74.74,71.69 53.98,13.02 78.16,70.37" fill="#F48FB1" />
    </svg>
</div>
패스(path) path 태그를 이용해 선으로 이루어진 복잡한 도형을 만듭니다.
<div class="svgBox svg3">
    <svg class="svg">
        <path fill="none" stroke="#880E4F" stroke-width="2" d="M7,154.667c0-82.358,65.152-149,145.667-149"/>
    </svg>
    <svg class="svg">
        <path fill="none" stroke="#880E4F" stroke-width="2" d="M151.534,123.547c-33.711,33.711-88.369,33.711-122.08,0
        c-26.97-26.969-26.97-70.695,0-97.665c21.575-21.576,56.556-21.576,78.131,0c17.261,17.26,17.261,45.245,0.001,62.504
        c-13.809,13.809-36.196,13.809-50.005,0c-11.046-11.046-11.046-28.956,0-40.002c8.837-8.837,23.166-8.837,32.003,0
        c7.069,7.07,7.07,18.532,0,25.602c-5.656,5.657-14.826,5.657-20.482,0c-4.524-4.524-4.524-11.86,0-16.385"/>
    </svg>
    <svg class="svg">
        <path fill="none" stroke="#880E4F" stroke-width="2" d="M82.671,81.243c50.565,48.259,14.182,69.191-2.135,1.229
        c16.316,67.962-25.611,65.895-2.46-0.122c-23.151,66.017-57.304,41.617-2.004-1.432c-55.3,43.049-70.84,4.057-0.912-2.288
        c-69.929,6.345-61.919-34.86,0.47-2.417c-62.389-32.442-33.374-62.777,1.703-1.78c-35.076-60.997,5.73-70.826,2.395-0.577
        c3.335-70.249,42.981-56.458,2.326,0.81c40.655-57.268,66.554-24.232,1.521,1.938c65.033-26.17,68.953,15.62,0.23,2.452
        C152.526,92.225,133.236,129.502,82.671,81.243z"/>
    </svg>
    <svg class="svg">
        <path fill="none" stroke="#880E4F" stroke-width="2" d="M131.502,129.683c-44.4-42.871-49.621-39.867-34.943,20.102
        c-14.678-59.969-20.694-60.265-40.261-1.983c19.566-58.281,14.666-61.783-32.799-23.436C70.963,86.018,68.733,80.421,8.573,86.918
        c60.16-6.497,61.31-12.409,7.692-39.569c53.617,27.16,57.781,22.808,27.864-29.131c29.917,51.938,35.772,50.527,39.189-9.441
        c-3.417,59.969,2.272,61.948,38.075,13.245c-35.803,48.703-32.086,53.443,24.869,31.726C89.308,75.465,89.87,81.462,150.03,93.884
        C89.87,81.462,87.102,86.812,131.502,129.683z"/>
    </svg>
    <svg class="svg">
        <path fill="none" stroke="#880E4F" stroke-width="2" d="M58.665,139.312c0-6.873,42-6.873,42-13.747s-42-6.874-42-13.748
        s42-6.874,42-13.748c0-6.872-42-6.872-42-13.744c0-6.874,42-6.874,42-13.747c0-6.877-42-6.877-42-13.753
        c0-6.874,42-6.874,42-13.748c0-6.878-42-6.878-42-13.757s42-6.879,42-13.758"/>
    </svg>
    <svg class="svg">
        <path fill="none" stroke="#880E4F" stroke-width="2" d="M93.108,91.478c42.049,30.58-13.048,57.425-13.347,6.503
        c0.299,50.922-55.041,24.58-13.405-6.381c-41.636,30.961-55.545-28.728-3.37-14.458c-52.176-14.27-14.181-62.359,9.204-11.649
        c-23.385-50.71,37.901-50.989,14.846-0.067c23.055-50.922,61.484-3.179,9.309,11.565C148.521,62.245,135.157,122.058,93.108,91.478
        z"/>
    </svg>
</div>
라인
(line, polyline)
line 태그를 이용해 선을 만듭니다. 꼭직점이 있는 선은 polyline 태그를 이용합니다.
<div class="svgBox svg3">
    <svg>
        <line x1="0" y1="0" x2="200" y2="200" stroke="#0D47A1" stroke-width="2" fill="none" />
    </svg>
    <svg>
        <line x1="50" y1="50" x2="200" y2="200" stroke="#0D47A1" stroke-width="2" fill="none" />
    </svg>
    <svg>
        <line x1="100" y1="100" x2="200" y2="200" stroke="#0D47A1" stroke-width="2" fill="none" />
    </svg>
    <svg>
        <polyline points="21,17.2 21,139.2 117,52.2" stroke="#0D47A1" stroke-width="2" fill="none" />
    </svg>
    <svg>
        <polyline points="21,17.2 21,139.2 122,28.2 141,139.2" stroke="#0D47A1" stroke-width="2" fill="none" />
    </svg>
    <svg>
        <polyline points="21,17.2 21,139.2 122,28.2 141,139.2 23.5,11.7" stroke="#0D47A1" stroke-width="2" fill="none" />
    </svg>
</div>

> 클리핑 마스크(Clip-path)

SVG의 클리핑 마스크 기능인 clipPath 태그를 이용하여 SVG 이미지에 다른 이미지를 클립할 수 있습니다.

설명 내용
예시
코드
<div class="svgBox svg3">
    <svg>
        <image xlink:href="https://github.com/hjkang306/coding2/blob/main/animation/img/bg2.png?raw=true" width="160" height="160"/>
    </svg>
    <svg>
        <image xlink:href="https://github.com/hjkang306/coding2/blob/main/animation/img/bg2.png?raw=true" width="160" height="160" clip-path="circle(60px at center)"/>
    </svg>
    <svg>
        <clipPath id="clipPath1">
            <polygon points="136,141 10,101 108,12" fill="#F48FB1" />
        </clipPath>
        <image xlink:href="https://github.com/hjkang306/coding2/blob/main/animation/img/bg2.png?raw=true" width="160" height="160" clip-path="url(#clipPath1)"/>
    </svg>
    <svg>
        <clipPath id="clipPath2">
            <polygon points="121,131 56,140 15,89 39,27 104,18 145,70" fill="#F48FB1"/>
        </clipPath>
        <image xlink:href="https://github.com/hjkang306/coding2/blob/main/animation/img/bg2.png?raw=true" width="160" height="160" clip-path="url(#clipPath2)"/>
    </svg>
    <svg>
        <clipPath id="clipPath3">
            <polygon points="115,134 71,144 30,124 12,82 26,39 64,14 108,20 139,53 142,98" fill="#F48FB1" />
        </clipPath>
        <image xlink:href="https://github.com/hjkang306/coding2/blob/main/animation/img/bg2.png?raw=true" width="160" height="160" clip-path="url(#clipPath3)"/>
    </svg>
    <svg>
        <clipPath id="clipPath4">
            <polygon points="133,129 87,115 50,144 49,96 9,70 54,54 67,8 96,47 144,45 116,84" fill="#F48FB1" />
        </clipPath>
        <image xlink:href="https://github.com/hjkang306/coding2/blob/main/animation/img/bg2.png?raw=true" width="160" height="160" clip-path="url(#clipPath4)"/>
    </svg>
</div>

> 클리핑 마스크(Clip-path)

SVG 텍스트에 클리핑 마스크 기능을 이용해 이미지를 클립합니다.

설명 내용
예시

See the Pen svg clipping by hjkang306 (@hjkang306) on CodePen.

HTML
<div class="svgBox svg7">
    <svg>
        <text fill="#f48fb1" x="7" y="110" font-family="SCoreDream" font-size="70" font-weight="900">SVG</text>
    </svg>
    <svg>
        <pattern id="pattern1" patternunites="useSpaceOuUse" width="100%" height="100%">
            <image xlink:href="img/bg2.png" width="160" height="160" />
        </pattern>
        <text fill="url(#pattern1)" x="7" y="110" font-family="SCoreDream" font-size="70" font-weight="900">SVG</text>
    </svg>
    <div class="text__wrap">
        <div class="text-clip c1">SVG</div>
    </div>
    <div class="text__wrap">
        <div class="text-clip c2">SVG</div>
    </div>
    <div class="text__wrap">
        <div class="text-clip c3">SVG</div>
    </div>
    <div class="text__wrap">
        <div class="text-clip c4">SVG</div>
    </div>
</div>
CSS
.svg7 {display: flex;}
.text__wrap {
    background-color: #e3f3f4;
    width: 160px;
    height: 160px;
    margin: 6px;
    display: inline-block;
    overflow: hidden;
}
.text-clip {
    font-size: 70px;
    text-align: center;
    font-family: 'SCoreDream';
    text-transform: uppercase;
    line-height: 170px;
    -webkit-text-fill-color: #0d47a1;
}
.text-clip.c2 {
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    background-image: url(img/bg2.png);
    background-size: 100%;
}
.text-clip.c3 {
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    background-image: linear-gradient(60deg, #ff5858, #f09819);
}
.text-clip.c4 {
    -webkit-text-fill-color: transparent;
    -webkit-background-clip: text;
    -webkit-text-stroke: 2px #0d47a1;
}

> SVG 애니메이션

SVG 이미지의 stroke 속성과 dashoffset 속성을 이용하여 애니메이션을 만듭니다.

설명 내용
예시

See the Pen SVG animation by hjkang306 (@hjkang306) on CodePen.

HTML
<div class="svgBox svg8">
    <svg>
        <rect class="ani1"></rect>
    </svg>
    <svg>
        <rect class="ani2"></rect>
    </svg>
    <svg style="background: #E3F3FD">
        <path class="ani3" fill="none" stroke="#0D47A1" stroke-width="2" d="M7,154.667c0-82.358,65.152-149,145.667-149"/>
    </svg>
    <svg style="background: #E3F3FD">
        <path class="ani4" fill="none" stroke="#0D47A1" stroke-width="2" d="M151.534,123.547c-33.711,33.711-88.369,33.711-122.08,0
c-26.97-26.969-26.97-70.695,0-97.665c21.575-21.576,56.556-21.576,78.131,0c17.261,17.26,17.261,45.245,0.001,62.504
c-13.809,13.809-36.196,13.809-50.005,0c-11.046-11.046-11.046-28.956,0-40.002c8.837-8.837,23.166-8.837,32.003,0
c7.069,7.07,7.07,18.532,0,25.602c-5.656,5.657-14.826,5.657-20.482,0c-4.524-4.524-4.524-11.86,0-16.385"/>
    </svg>
    <svg style="background: #E3F3FD">
        <path class="ani5" fill="none" stroke="#0D47A1" stroke-width="2" d="M58.665,139.312c0-6.873,42-6.873,42-13.747s-42-6.874-42-13.748
        s42-6.874,42-13.748c0-6.872-42-6.872-42-13.744c0-6.874,42-6.874,42-13.747c0-6.877-42-6.877-42-13.753
        c0-6.874,42-6.874,42-13.748c0-6.878-42-6.878-42-13.757s42-6.879,42-13.758"/>
    </svg>
    <svg style="background: #E3F3FD">
        <path class="ani6" fill="none" stroke="#0D47A1" stroke-width="2" d="M93.108,91.478c42.049,30.58-13.048,57.425-13.347,6.503
        c0.299,50.922-55.041,24.58-13.405-6.381c-41.636,30.961-55.545-28.728-3.37-14.458c-52.176-14.27-14.181-62.359,9.204-11.649
        c-23.385-50.71,37.901-50.989,14.846-0.067c23.055-50.922,61.484-3.179,9.309,11.565C148.521,62.245,135.157,122.058,93.108,91.478
        z"/>
    </svg>
</div>
CSS
.ani1 {
    width: 100px; height: 100px;
    x: 30px; y: 30px;
    fill: none;
    stroke: #880E41;
    stroke-width: 2px;
    stroke-dasharray: 50;
    stroke-dashoffset: 50;
    animation: ani1 1s infinite linear alternate-reverse;
}
@keyframes ani1 {
    0%   {stroke-dashoffset: 50;}
    100% {stroke-dashoffset: 0;}
}
.ani2 {
    width: 100px; height: 100px;
    x: 30px; y: 30px;
    fill: none;
    stroke: #880E41;
    stroke-width: 2px;
    stroke-dasharray: 400;
    stroke-dashoffset: 400;
    animation: ani2 2s infinite linear alternate-reverse;
}
@keyframes ani2 {
    0%   {stroke-dashoffset: 400;}
    100% {stroke-dashoffset: 0;}
}
.ani3 {
    animation: ani3 1s infinite linear alternate-reverse;
    stroke-dasharray: 230px;
    stroke-dashoffset: 230px;
}
@keyframes ani3 {
    0%   {stroke-dashoffset: 230px;}
    100% {stroke-dashoffset: 0;}
}
.ani4 {
    animation: ani4 1s infinite linear alternate-reverse;
    stroke-dasharray: 605px;
    stroke-dashoffset: 605px;
}
@keyframes ani4 {
    0%   {stroke-dashoffset: 605px;}
    100% {stroke-dashoffset: 0;}
}
.ani5 {
    animation: ani5 1s infinite linear alternate-reverse;
    stroke-dasharray: 411px;
    stroke-dashoffset: 411px;
}
@keyframes ani5 {
    0%   {stroke-dashoffset: 411px;}
    100% {stroke-dashoffset: 0;}
}
.ani6 {
    animation: ani6 1s infinite linear alternate-reverse;
    stroke-dasharray: 614px;
    stroke-dashoffset: 614px;
}
@keyframes ani6 {
    0%   {stroke-dashoffset: 614px;}
    100% {stroke-dashoffset: 0;}
}

See the Pen Text Animation by hjkang306 (@hjkang306) on CodePen.

728x90

댓글


HTML이 적힌 썸네일 이미지
CSS가 적힌 썸네일 이미지
JAVASCRIPT가 적힌 썸네일 이미지

JAVASCRIPT

자세히 보기