• [SVG] The Gooey Effect

    2019. 9. 18.

    by. 나나 (nykim)

    320x100

    [글 출처] The Gooey Effect - Lucas Bebber from CSS-TRICKS

     

     

    요약: 대충 SVG를 가지고 구이구이한 효과를 만드는 이야기

     

     


     

     

    1. SVG 필터

     

    자, SVG 필터는 다음과 같이 작성합니다.

    caniuse.com에 따르면 IE 10, Android 4.4 부터 지원하는 기능입니다.

    필요한 경우 -webkit-filter 처럼 프리픽스를 넣어 주세요,

     

    <svg>
      <defs>
        <filter id="filter-id">
          <!-- Insert filters here! -->
        </filter>
      </defs>
    </svg>

     

    모든 SVG 필터는 <defs> 요소 안에 정의됩니다. (defs = definitions 거든요!)

    만들어 둔 필터를 적용하려면 아래와 같이 작성합니다 ;^)

     

    .selector {
      filter: url('#filter-id');
    }
    
    /* 
     * 또는 아래처럼 외부 SVG의 필터를 적용할 수도 있어요!
     * (대신 IE와 Edge는 미지원인 듯 합니다)
     */
    
    .selector2 {
      filter: url('filters.svg#filter-id');
    }

     

    예제를 살펴보죠.

    우선 아이디가 blur인 필터를 만듭니다.

     

    <filter id="blur">
      <feGaussianBlur in="SourceGraphic" stdDeviation="3" />
    </filter>

     

    위 필터는 3px 짜리 블러 효과를 줄 것입니다. 그런데 in="SourceGraphic" 이라는 특이한 속성이 있네요.

    in 속성은 *필터 프리미티브(a filter primitive)에 대한 입력을 정의합니다. SourceGraphic은 필터가 적용되기 전 오리지널 요소를 가리킵니다.

    그러니까 결국 오리지널 그래픽에다가 블러 효과를 주어라, 란 뜻이 되겠네요.

     

    * filter primitive
    The set of elements that control the output of a filter element, particularly: feSpotLightfeBlendfeColorMatrixfeComponentTransferfeCompositefeConvolveMatrixfeDiffuseLightingfeDisplacementMapfeDropShadowfeFloodfeGaussianBlurfeImagefeMergefeMorphologyfeOffsetfeSpecularLightingfeTilefeTurbulence.

     

    See the Pen svg blur demonstration by Lucas Bebber (@lbebber) on CodePen.

     

    앗, 그럼 저 말을 다르게 표현하면 오리지널이 아닌 다른 데다가도 효과를 줄 수 있다는 뜻이 되겠네요?!

    얼른 다른 예제도 확인해봅시다.

     

    <filter id="drop-shadow">
      <feGaussianBlur in="SourceGraphic" stdDeviation="7" result="shadow" />
      <feOffset in="shadow" dx="3" dy="4" result="shadow" />
      <feColorMatrix in="shadow" type="matrix" values="0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 0.6 0" result="shadow" />
      <feBlend in="SourceGraphic" in2="shadow" />
    </filter>

     

    조금 더 복잡한 예제가 나왔습니다. 하지만 차근차근 해독하면 어렵지 않은 내용이에요.

     

    첫번째 필터를 보니 result라는 속성이 눈에 띕니다. 보아하니 이 속성으로 필터 결과에 이름을 붙이고, 그 결과에다가 또 다른 핕러를 적용할 수 있게 하는 모양입니다. 그러니까 결국 오리지널 그래픽에 7px짜리 블러를 준 다음, 그 결과물에 shadow란 이름을 붙인 거죠.

     

    feOffset은 현재 위치에서 설정한 만큼 이동할 수 있게 합니다. dx/dy는 요소가 있는 위치에서 x축/y축으로 n만큼 이동하라는 뜻입니다. x/y가 절대 좌표라면 dx/dy는 상대 좌표입니다. 그러니 원래 요소가 있던 위치에서 x축으로 3px, y축으로 4px만큼 이동하라는 게 되겠네요. 잘 보면 in과 result가 모두 shadow로 지정된 걸 알 수 있습니다.

     

    feColorMatrix는 RGBA 값을 적용하는 건데... 색상 matrix를 여기서 다루기엔 지면이 부족(?)한 관계로 나중에 살펴보겠습니다.

     

    마지막으로 feBlend 프리미티브는 여러 입력(inputs)을 혼합할 수 있게 합니다. in 속성으로 오리지널 그래픽 요소(파란색 박스)를, in2 속성을 통해 우리가 필터를 적용한 요소(shadow)를 가져와 혼합되게 한 거죠.

     

    그래서 아래와 같은 결과물이 보이게 됩니다.

     

     

    See the Pen svg drop shadow demonstration by Lucas Bebber (@lbebber) on CodePen.

     

     


     

     

     

    2. 끈적거리게 만들기

     

    SVG 필터에 대해 가볍게 살펴봤으니, 본격적으로 구이 효과를 만들어 보겠습니다.

    여기 CSS 필터로 blur와 contrast를 활용해 이런 효과를 낸 예제가 있습니다.

     

     

    See the Pen Simple Gooey by NY KIM (@nykim_) on CodePen.

     

     

    쉽고 간단하네요! 하지만 문제가 있습니다: 흑백 외에는 처리가 힘들다는 것, blur 처리되므로 활용히 힘들다는 것, background를 반드시 필요로 하므로 투명한 배경을 만들 수 없다는 것.

     

    그래서 SVG 필터를 사용하는 것입니다. 우리는 색상을 검정으로 바꾸지 않고 오로지 알파 채널의 contrast만 조절할 수가 있습니다. 여기에 SourceGraphic을 가지고 오리지널 그래픽 요소가 보이게 처리하면 됩니다. 또, 알파 채널을 다룰 것이므로 투명한 배경이 필요하다는 점을 기억해 두세요 :>

     

    여기, 코드가 있습니다.

     

    <filter id="goo">
      <feGaussianBlur in="SourceGraphic" stdDeviation="10" result="blur" />
      <feColorMatrix in="blur" type="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7" result="goo" />
      <feBlend in="SourceGraphic" in2="goo" />
    </filter>

     

     

    하나하나 살펴보면,

    1. SourceGraphic(오리지널 그래픽)에 10px 블러를 주고 이름을 blur라고 함
    2. 그 blur에 컬러 매트릭스 필터를 적용해 알파 채널의 contrast를 올리고 그걸 goo라고 함
    3. 오리지널 그래픽과 우리가 만든 효과(goo)가 겹쳐지도록 함

    의 단계를 거친 걸 알 수 있습니다.

     


     

     

    3. 컬러 매트릭스

     

    음... 근데 컬러 매트릭스가 뭐죠?

    대충 이렇게 생긴 겁니다.

     

       | R | G | B | A | +
    ---|-------------------
     R | 1 | 0 | 0 | 0 | 0
    ---|-------------------
     G | 0 | 1 | 0 | 0 | 0
    ---|-------------------
     B | 0 | 0 | 1 | 0 | 0
    ---|-------------------
     A | 0 | 0 | 0 | 1 | 0
    ---|-------------------

     

    우와, 정말 보기 싫게 생겼네요! Σ(゚д゚;)

     

    세로 축에 보이는 4개의 RGBA는 오리지널 그래픽의 채널 값을 나타냅니다.

    셀의 숫자는 해당 행에 열로 표시되는 채널의 값을 곱한 결과입니다.

    행 R + 열 G가 0.5라면 초록빛 50%를 빨간 채널에 추가한 느낌...같은 거죠.

    마지막에 +로 표시된 값은... 음... 그 채널에 255를 곱한 만큼 추가/제거되는 값입니다.

    (어휴 이게 몬소리야)

     

    출처: https://css-irl.info/into-the-matrix-with-svg-filters/

     

    아무 조작도 하지 않은 이미지라면, 기본 채널 값은 RGBA 모두 {1, 1, 1, 1} 일 것입니다.

    이 값을 조절하면서 감을 익혀보죠.

    이 곳에서 SVG Color Filter를 실험해볼 수 있습니다.

     

     

    👆이 이미지를 가지고 조작해볼게요!

     

     

    우선 RGBA 중에서 G와 A만 1로 남기고 다른 값은 0으로 해보겠습니다.

     

     

    그럼 저런 값과 형태가 나오네요.

    오로지 초록빛만 남았으니 이미지가 초록빛으로 나오겠죠.

     

    이번엔 1열만 건드려볼게요. 

     

     

    노랗게 바뀌었어요! 빛의 3원색을 혼합했을 때 어떻게 되는지 생각하면 당연한 결과죠.

    결국 컬러 매트릭스란 무슨 빛을 얼만큼 섞을 거냐를 표로 나타낸 거라 보면 됩니다.

     

    이 값을 세밀하게 조절하면 이런 인스타St.의 필터를 만들 수도 있고요.

     

     

    어후, 이제 본론으로 돌아가죠.

    저어기 위에서 작성한 컬러 매트릭스 값은 아래와 같았습니다.

     

       | R | G | B | A | +
    ---|-------------------
     R | 1 | 0 | 0 | 0 | 0
    ---|-------------------
     G | 0 | 1 | 0 | 0 | 0
    ---|-------------------
     B | 0 | 0 | 1 | 0 | 0
    ---|-------------------
     A | 0 | 0 | 0 |1𝟪 |-7
    ---|-------------------

     

    그러니 이 매트릭스는,

    컬러값은 그대로 냅두되 알파채널 값에 18을 곱한 다음,

    그 값에서 7*255를 빼서 투명도의 contrast만 올린 게 됩니다.

    (어휴 이게 몬소리야2222)

     

    어쨌든 저 값을 feColorMatrix에 넣을 수 있게 바꾼다면 아래와 같은 형태가 됩니다.

     

    values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 18 -7"

     

    주의할 점은, 필터는 반드시 요소의 컨테이너에 적용되어야 합니다.

    또한 blur처리 하는 과정에서 본래 크기보다 커지기 때문에 그걸 고려해 크기 계산을 해야 합니다.

    그리고 쭈우욱 늘어나는 요소는 본래 요소와 동일한 위치에 투명하게 숨겨져 있습니다. 따라서 쭈우욱 늘어나는 요소(코드에서 result라 명명한 그것)에게 컬러 매트릭스를 줄 때, 너무 작은 값을 주면 모서리 번짐 현상이 발생할 수도 있습니다.

     

    아래 결과 화면으로 Gooey 효과를 확인해 보세요 ˚✧₊⁎( ˘ω˘ )⁎⁺˳✧༚

     

     

    See the Pen Goooooey by NY KIM (@nykim_) on CodePen.

     

    728x90

    'Blog > Web Animation' 카테고리의 다른 글

    [SVG] SVG 다루기  (10) 2019.09.16

    댓글