ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [에스비지] SVG -(10편)- 곡선따라 글 쓰기 (feat. defs, path, text, textPath, href, tspan)
    SVG 2021. 2. 6. 21:40

    Again, we got this!

    이번에는

     

    곡선을 따라 글을 적는 것을 해보자.

     

    일러스트레이터나 포토샵에서 많이 해봤을 것이다.

     

    패스를 그리고 그 패스에다가 text툴을 찍어서 패스를 따라 글이 배치되는 것을.

     

     

     

    그렇다면, svg는 다를까?

     

    크게 다르지 않다.

     

    결국 우리가 필요한 것은 pass가 아닌 path다!

     

    path 를 지난시간에 다룬적이 있다.

    모르겠다면 링크 참조!

     

    https://blog.naver.com/nicholasdw/222233249293

     

    [에스비지] SVG (Scalable Vector Graphics) -(06편)- path(패스)로 그리기 (feat. M, L, Q, C, H, V, Z, A)

    #svg #svg그리기 #에스비지 #에스비지그리기 #에스비지직접그리기 #path​​로 ...

    blog.naver.com

     

     

     

    다시 돌아와서,

     

    우선 svg 태그를 만들고 그안에 text태그로 lorem20 정도로 더미 텍스트를 넣어보자.

    lorem20 적은 후 띄어쓰기 하지 않은 상태에서 tab키!

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>곡선따라 글쓰기</title>
      <style>
        .svg {
          width: 1000px;
          height: 700px;
          background: #eee;
        }
        text {
          fill: dodgerblue;
          font-size: 17px;
          font-weight: bold;
        }
      </style>
    </head>
    <body>
      <svg class="svg">
        <text x="10" y=100>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab suscipit rem similique quis et ad rerum iste in illum natus!</text>
      </svg>
    </body>
    </html>

     

     

    그리고 svg 영역 잡아주고,text 색깔 크기 굵기 등을 설정했다.

     

    위 화면과 같이 나온다.

     

    자 여기서 패스까지 그려보자.

    곡선으로!

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>곡선따라 글쓰기</title>
      <style>
        .svg {
          width: 1000px;
          height: 700px;
          background: #eee;
        }
        text {
          fill: dodgerblue;
          font-size: 17px;
          font-weight: bold;
        }
        .path {
          fill: transparent;
          stroke: crimson;
          stroke-width: 5;
        }
      </style>
    </head>
    <body>
      <svg class="svg">
        <path class="path" d="M 10 300 Q 100 250 200 300 q 100 50 200 0 q 100 -50 200 0 q 100 50 200 0 q 100 -50 150 0"></path>
        <text x="10" y=100>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab suscipit rem similique quis et ad rerum iste in illum natus!</text>
      </svg>
    </body>
    </html>

     

     

    패스를 그려줬다.

    (아래는 위의 path 태그 그린걸 설명하고 있다.)


    d 속성에 M으로 모조건 기준점을 잡고

    시작해야 한다고 했다.

     

    그리고 곡선을 그려줄것이기에 Q나 C를 이용하여 적으면 된다.

    C는 시작위치를 매번 적어줘야하는 반면,

    Q는 시작위치를 생략하고 중간점(핸들러)과 끝점만 잡아주면 되는 것이라서,

    코드가 좀 더 간결하다.

     

    그리고 대문자와 소문자는

    절대위치와 상대위치를 나타내므로,

    Q는 영역안의 절대좌표를 기준으로 잡아준다면,

    q는 현재 위치한 점에서부터 x값과 y값의 상대 위치로 이동하며 그린다고 생각하면 된다.

     

    위의 링크를 통해 한번 더 복습하고 보면 좋을 것 같다.


    그러면 결과물은

     

     

    이런 모습이다.

     

    이쁘게 잘 그렸다.

     

    물론 이렇게 그리지 않고,

    일러스트레이터에서 그려서 거기서 코드를 받아서 사용해도 무방하다.

    그게 더 내가 원하는대로 세밀하게 조정하능하겠다.

     

     

     

     

    자!

        이제 우리가 적은 텍스트가 우리가 그린 곡선을 참조해서    

        그것의 형태에 맞게끔 변형을 해 줘야한다.    

     

    어떻게???

     

     

     

    여기서 우리가 필요한게 이거다.

         <defs></defs>     

     

     

    과연 이 defs가 뭘까???

     

    defs는 definitions 정의들 이렇게 해석이 된다.

     

     

        MDN mozilla 에서 설명  하는 것은

    The <defs> element is used to store graphical objects that will be used at a later time. Objects created inside a <defs> element are not rendered directly. To display them you have to reference them (with a <use> element for example).

    Graphical objects can be referenced from anywhere, however, defining these objects inside of a <defs> element promotes understandability of the SVG content and is beneficial to the overall accessibility of the document.

     

    ((     <defs> 엘리먼트는 나중에 사용될 그래픽 오브젝트를 저장하는 데에 사용된다.

    <defs> 엘리먼트 안에 생성된 오브젝트들은 바로 렌더 되는게 아니다.

    그들을 보여주기 위해서는 <use>엘리먼트와 함께 그들을 참조시켜야 한다. 

     

    그래픽 오브젝트들은 어디서든 참조될 수 있지만, <defs>엘리먼트 안의 이러한 오브젝트들을 정의하는 것은 그 svg 컨텐츠의 이해를 높이고, 문서의 전반적인 접근에 유익하다.   )) 

     

     

     

    이렇게 설명하고,

     

        w3school 에서 

     

    간단하게

    The <defs> element is a container element for referenced elements.

     

    ((   <defs>엘리먼트는 참조되는 엘리먼트들의 컨테이너(묶음) 엘리먼트이다.  ))

     

     

     

    포인트는

    Elements that are descendants of a 'defs' are not rendered directly. However, that the descendants of a 'defs' are always present in the source tree and thus can always be referenced by other elements.

    ((     

    defs 의 자손인 엘리먼트들은 바로 렌더되지 않는다. 

    하지만, defs의 자손들은 그 소스트리 안에서 항상 있기 때문에 항상 다른 엘리먼트들로 부터 참조될 수 있다.

      ))

     

     

     

     

    해석해보면 결국 둘다 같은 말을 한다.

     

     

     

     

    1분코딩님 왈,

     

    "나중에 참조할 그래픽 요소 같은 것들을 담아놓는 공간이라고 보시면 돼요."

     

     

     

    따라서,

     

    우리가 그린 <path>를 참조해서 텍스트를 그릴 것이기 때문에,

    defs 안에 path를 옮긴다.

     

     

    like below(아래 처럼),

     

     

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>곡선따라 글쓰기</title>
      <style>
        .svg {
          width: 1000px;
          height: 700px;
          background: #eee;
        }
        text {
          fill: dodgerblue;
          font-size: 17px;
          font-weight: bold;
        }
        .path {
          fill: transparent;
          stroke: crimson;
          stroke-width: 5;
        }
      </style>
    </head>
    <body>
      <svg class="svg">
        <defs>
          <path class="path" d="M 10 300 Q 100 250 200 300 q 100 50 200 0 q 100 -50 200 0 q 100 50 200 0 q 100 -50 150 0"></path>
        </defs>
        <text x="10" y=100>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab suscipit rem similique quis et ad rerum iste in illum natus!</text>
      </svg>
    </body>
    </html>

     

     

    그러면,

    화면이 어떻게 변하냐면,

     

    우리가 그렸던 path가 눈에서 보이지 않게 된다.코드는 존재하지만,참조하는 컨테이너인 defs 안에 담겼기 때문에,눈에만 보이지 않는 것이다.

     


    defs의 용도는 path나 도형을 넣어 둘 수도 있고,조만간에 배울 그라디언트 나 마스크 등을 정의해서 넣어둘 수 있다.그런건 다음에 차차 배울테니 지금은 생각하지 말자.다만, 매우 유용하다는 것은 기억하자. 

     

    style도 svg 태그안에 옮겨놓을 수 있다는 것을 배웠었다.

    svg안에 defs 안에 넣어둬도 물론 작동에 상관이 없다. 참조용이기 때문에.

     

    이해가 안간다면 무시해도 좋다.

    지금 배우는것에 지장없다.

    차차 알게 될 것이다.


    자!

    그러면, 이 path에 텍스트를 어떻게 적용할까?????


    1.

    <path />에 id를 지정하자.

        <path id="text-curve" />    

     

    2.

    <text></text> 안에 <textPath></textPath>를 넣은 후,

    href="" 안에 id값을 연결하자.

     

        <textPath href="#text-curve">lorem20</textPath>    

     


    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>곡선따라 글쓰기</title>
      <style>
        .svg {
          width: 1000px;
          height: 700px;
          background: #eee;
        }
        text {
          fill: dodgerblue;
          font-size: 17px;
          font-weight: bold;
        }
        .path {
          fill: transparent;
          stroke: crimson;
          stroke-width: 5;
        }
      </style>
    </head>
    <body>
      <svg class="svg">
        <defs>
          <path id="text-curve" class="path" d="M 10 300 Q 100 250 200 300 q 100 50 200 0 q 100 -50 200 0 q 100 50 200 0 q 100 -50 150 0"></path>
        </defs>
        <text x="10" y=100>
          <textPath href="#text-curve">
            Lorem ipsum dolor sit amet, consectetur adipisicing elit. Ab suscipit rem similique quis et ad rerum iste in illum natus!
          </textPath>
        </text>
      </svg>
    </body>
    </html>

     

    위처럼 작성하면,

    화면은?

     

        짠!!    

     

     

     

     

    나중에 우리가 애니메이션을 적용하면

    곡선이 다양하게 구부러지며 변화되면 텍스트도 같이 움직이는 것도 가능하다.

     

     


    훌륭히 잘 따라왔다.

     

    여기에서 만약 우리가 저 텍스트들 중 몇 단어를 강조하고 싶다면??

     

     

     

     

     

    기존에는 span이라는 태그로 마크업해서 css로 꾸며줬었다면,여기에서는

     

        <tspan></tspan>    

    을 사용한다.

     

     

     

     

     

     

    아래의 예를 보자.

     

     

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>곡선따라 글쓰기</title>
      <style>
        .svg {
          width: 1000px;
          height: 700px;
          background: #eee;
        }
        text {
          fill: dodgerblue;
          font-size: 17px;
          font-weight: bold;
        }
        .path {
          fill: transparent;
          stroke: crimson;
          stroke-width: 5;
        }
        tspan {
          font-weight: normal;
          fill: crimson;
          font-size: 50px;
        }
      </style>
    </head>
    <body>
      <svg class="svg">
        <defs>
          <path id="text-curve" class="path" d="M 10 300 Q 100 250 200 300 q 100 50 200 0 q 100 -50 200 0 q 100 50 200 0 q 100 -50 150 0"></path>
        </defs>
        <text x="10" y=100>
          <textPath href="#text-curve">
            Lorem ipsum dolor <tspan>sit amet,</tspan> consectetur adipisicing elit. Ab suscipit rem similique quis et ad rerum iste in illum natus!
          </textPath>
        </text>
      </svg>
    </body>
    </html>

    강조하고픈 단어나 문장을 tspan 태그로 묶어서 css로 변화를 주었다.아래처럼,

     

     

    Wow!!!

     

     

    여기서 드는 궁금증 하나,

     

    span은 적용 안될까?

     

    그래서 해봤다.

     

     

       안된다   

     

     

    vscode 에디터에서는 안된다고 빨간글씨로 변하고,화면상에도 글씨가 영역밖으로 벗어나며 이상해진다.

     

    text태그나 textPath 안에서는

    tspan만 된다는걸 기억하자!

     

Designed by Tistory.