Studying/HTML | CSS

끝부분이 늘어나는 효과

Kim Da Ham 2023. 5. 9. 09:52

 

공부할 자료

 

See the Pen Ink Cursor by Webstoryboy (@webstoryboy) on CodePen.

 

 


 

 

분석하려는 것

물체의 끝부분이 쫀득하게 늘어나는 걸 어떻게 구현했는지 분석해보자!

 

그 외에도,

 

  • 마우스를 가만히 놔둘 때 커서가 꿈틀거림
  • 마우스의 이동 속도만큼 꼬리가 길거나 짧게 늘어남
  • 커서와 Hover Me 글자/배경이 겹쳐지면 반전 색이 나타남
  • (지금 당장 중요치 않지만 추가) 우측 상단에 빙글빙글 도는 글자

 

같이 눈에 두드러지는 특징들 위주로 알아보자.

 

 

 

내가 처음 보는 것

  • TweenMax 라이브러리
  • Stylus 전처리기

 

 

이 두가지에 대해서도 공부하고 해당 작품에 접근해야겠다.

 

 

 

 

그럼 시작!

 

 

 

Stylus 전처리기

Stylus 이란, CSS 전처리기(Pre-Processor) 중 하나이다.

 

CSS 전처리기는 자신만의 특별한 문법을 가지고 CSS를 생성하는 프로그램이다. 기존 CSS에는 존재하지 않는 문법을 사용하여 CSS 파일의 가독성을 높이고 더 높은 유지보수성을 끌어올린다. Color 값을 찾거나, 괄호를 닫는 번거로운 작업을 없애곤 한다.(예를 들어 color를 매번 색상코드로 찾지 않고 변수로 처리해 하나의 파일 안에 color-set을 정의한다)

 

즉 CSS에 프로그래밍적인 개념을 삽입하여 변수, 함수, 상속 등을 사용하면서 편한 유지 관리를 제공하는 게 궁극적인 목적이다.

 

나는 대표적으로 SASS에 대해서만 알고있었고, 이것도 언젠간 배워야지... 하고 미루던 것 중 하나였다.

 

그런데 우연찮게 Stylus부터 공부하게 될 줄이야. (비교적 늦게 나온 전처리기라고...)

 

개인적으로 Stylus 문법은 아주 단순하고 한눈에 배우기 쉬운 것 같다. 일단 당장 보이는 특징으로는

 

  • 중괄호를 없애고
  • 세미콜론을 없애고
  • 반복을 줄이고(DRY 하다고 표현한다)
  • mixin을 보다 가독성있게(투명하게) 표현하고
  • 동적인 import을 지원하고
  • 함수 사용 가능하며
  • 이 모든 게 옵션일 뿐 필수는 아니다!

 

라는 멋진 기능들을 가지고 있다. 몇년 전에는 잔버그가 존재해서 잘 안쓰였지만 한 4년 전부터는 많이 쓰는 것 같다.

 

Stylus는 Node.js 기반으로 구동된다.

 

npm init

 

으로 package.json을 생성하고

 

npm install -g stylus

 

명령어로 설치한다.

 

그런 뒤 css 파일로 컴파일 하고 싶으면

 

stylus style.css

 

뒤에 파일명을 붙여 stylus 명령어를 수행하면 된다.

 

 

 

 

 

TweenMax 애니메이션 라이브러리

이것도 매우 초면인 친구다.

 

CodePen 코드를 vsCode로 옮기는데 정의되지 않은 객체가 있어서 보아하니 외부 라이브러리를 추가한 거였다.

(덕분에 CodePen에 외부 라이브러리 추가하는 법도 배움ㅎ)

 

어찌됐든,

 

 

TweenMax 라이브러리에 대해 알려면 가장 먼저 GSAP이 무엇인지 알고있어야 한다.

 

GSAP이란, 애니메이션을 CSS 키프레임이나 제이쿼리 보다 더 정밀하게 컨드롤 할 수 있는 "타임라인 기반의 애니메이션 JavaScript 라이브러리" 이다. 모든 프레임워크에서 JavaScript가 접근할 수 있는 거의 모든 것을 애니메이션으로 만들 수 있다고 한다. UI, SVG, Three.js, React 구성요소 모두 지원한다.

 

 *GSAP(The GreenSock Animation Platform)

 

 

적용 방법으로는 CDN, 공식 홈페이지에서 Download, npm 설치 등이 있다.

 

 

GSAP에는 TweenLite, TweenMax, TimelineLite, TimelineMax 4가지 도구가 존재하는데,

 

  • Tween : 단일 애니메이션. (ex. 좌에서 우로 박스가 이동하는 단 하나의 애니메이션 단위)
    • TweenLite - 모든 객체의 모든 속성을 애니메이션화 할 수 있는 가벼운 무게의 코어 플러그인
    • TweenMax - 가장 기능이 풍부하고 인기 있는 도구. TweenLite, TimelineLite, TimelineMax, CSSPlugin, AtrPlugin, 등 많은 것들이 EasePack 하나에 포함되어 있다.

 

  • TimelineLite - 애니메이션을 시간순차적으로 진행되도록 조작한다.
  • TimelineMax - 여러 객체를 동일한 애니메이션으로 순차 재생할 때 사용하기 좋다.

 

이중에서 이번 실습은 TweenMax를 사용한다.

 

 

🎁 트윈맥스 기초 배우기 참고자료(1)

🎁 트윈맥스 기초 배우기 참고자료(2)

 

 

 

 

 

HTML 구성

 

1. SVG 태그

index.html 파일에서 가장 먼저 눈에 들어오는 건 바로 svg 태그이다.

 

<SVG> 태그란 대체 뭘까?

 

우선 SVG가 무엇인지 부터 알아야겠다. w3schools에 따르면 SVG란,

 

  • 확장 가능한 벡터 그래픽(Scalable Vector Graphics)이다.
  • 주로 웹에서 그래픽을 정의한다.
  • 아무리 확대해도 일반 이미지처럼 품질이 떨어지지 않는다.

 

SVG 태그란,

 

  • 2차원 그래픽을 XML형식으로 표현한다.
  • SVG 그래픽을 담기 위한 요소다.
  • SVG 태그 내 원, 사각형, 다각형, 라인, path 등을 담을 수 있다.
  • SVG 파일의 모든 요소와 속성에 애니메이션을 추가할 수 있다.

 

 

SVG 그래픽은 일반적으로 이미지를 불러올 때 사용하는 <img> 태그로도 불러올 수 있다.

 

그런데 왜 SVG 태그를 사용할까? 바로

 

<img> 태그는 CSS로 SVG 내부를 제어할 수 없기 때문이다.

 

그래서 태그를 사용하여 인라인에 넣는 것이다.

 

또한 인라인 태그로 넣으면 이미지를 불러올 때마다 HTTP 요청 로드가 없다는 것! 단점은 그만큼 HTML 코드가 복잡해지고 이미지 파일 캐싱이 불가능 하다는 점.(로드 될 때마다 SVG 파일을 다시 읽어야 한다)

 

그러니까 이미지에 디테일한 조작을 할 필요 없으면 <img> 태그를 쓰고,

디테일한 조작을 해야하면 <svg> 태그를 쓰면 되겠다.

 

또는 <object> 태그를 사용한 인라인 작성법이 있다는데, 자세한 내용은 여기를 참고하자.

 

 

그렇다면 또 다른 궁금점, SVG와 Canvas는 무슨 차이가 있을까?

 

  • SVG는 2D 그래픽을 XML로 표현하는 마크업 언어다.
  • 그 자체로 DOM을 가진다. 스크립트 상에서 접근할 수 있으며 JavaScript 이벤트 핸들러를 등록할 수 있다.
  • SVG로 그려진 그림은 객체로 저장된다. SVG 객체의 속성이 변경되면 브라우저에서 자동으로 다시 렌더링 한다.
  • Canvas는 API다. canvas 요소를 렌더링하기 위해 JavaScript의 canvasAPI 혹은 WebGL API를 사용한다.
  • 도형은 스크립트를 통해 "즉시" 그려진 다음 렌더링 된 후 버려진다. 위치가 변경될 경우 모든 그림(그래픽에 가려진 부분 까지도)을 다시 그린다.

 

 

글이 길어질까봐 여기서 모두 정리하진 못 하지만, SVG 튜토리얼을 보고 공부한다.

 

 

그게 SVG라는 건 알겠고, 내가 코드에서 가장 먼저 맞닥뜨린 <svg> 태그는 다음과 같이 생겼다.

참고로 <svg> 태그는 SVG의 Root 태그이다.

 

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="800">
  • xmlns - XML NameSpace. XML 요소 간의 이름 충돌을 방지하는 용도로 사용되며 html과 svg에서 똑같이 표기하지만 다른 의미로 사용되는 요소에 대한 구분을 한다.(XHTML 스펙을 따르고 있다면 반드시 지정해준다.)
    • 대부분 네임스페이스는 URI 형식이다. 실제로 주소가 연결되는 건 아니고, URI 형식으로 정의할 뿐 단순 문자열로 인식한다. 따라서 네임스페이스 URI이라고도 한다.
    • 네임스페이스는 해당 요소 및 그 하위 요소에 대한 기본 네임스페이스가 된다.
    • xmlns:xlink 와 같이 특성이 지정된 경우가 있는데, 이는 보통 xlink(XML 외부 링크)를 통해 외부 파일이나 위치에 접근하기 위한 특성 접두사다.
    • SVG에 대한 네임스페이스는 반드시 http://www.w3.org/2000/svg 이다(버전 1.1), 

 

네임스페이스 예시는 아래와 같다.

<html xmlns="http://www.w3.org/1999/xhtml">
  <body>
    <!-- some XHTML tags here -->
    <svg xmlns="http://www.w3.org/2000/svg" width="300px" height="200px">
      <!-- some SVG tags here -->
    </svg>
    <!-- some XHTML tags here -->
  </body>
</html>

<html> 요소는 기본 네임스페이스를 XHTML로 선언한다. <svg> 요소는 그 안에서 svg 네임스페이스를 재정의 한다.

결론적으로 <svg> 를 제외한 나머지 <html> 요소와 자식 요소는 XHTML에 속한다.

 

🎁 네임스페이스 예시 참고

🎁 XML 네임스페이스

🎁 MDN/Namespaces crash course

 

  • version - SVG 문서가 어떤 명세를 따르고 있는지 표시한다.현재로써 유효하게 사용되는 버전은 1.0, 1.1 두 가지다.

 

 

이제 SVG 태그 전체를 바라보자.

 

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="800">
    <defs>
      <filter id="goo">
        <feGaussianBlur in="SourceGraphic" stdDeviation="6" result="blur" />
        <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 35 -15" result="goo" />
        <feComposite in="SourceGraphic" in2="goo" operator="atop"/>
      </filter>
    </defs>
</svg>
  • <defs> - Definition of special elements. 모든 SVG 필터는 <defs> 요소 안에 정의된다. 나중에 재사용하기 위해 그래픽 객체를 정의한다고 보면 된다. 주로 SVG 필터 같이 특별한 요소를 정의하는 데 사용된다.

🎁 MDN-<defs>

 

  • <filter> - SVG 필터를 정의하는 요소. 각 필터를 구분하기 위해 id 속성을 넣어줘야 한다.
  • <feGaussianBlur> - 블러 효과를 정의하는 요소.
    • in : 필터를 적용시킬 요소. SourceGraphic이란 필터 요소를 적용할 오리지널 요소를 말한다. 
    • stDeviation : 흐림 정도. 수치가 높을 수록 번진다.
    • result - 필터 결과에 이름을 붙이고, 그 결과에 또 다른 필터를 적용할 수 있게 한다.

 

  • <feColorMatrix> - 픽셀별 색상 조정을 위한 필터이다. 변환 행렬을 기반으로 색상을 바꾸어서 Matrix라는 이름을 가졌다. mode와 values 값을 기준으로 각 픽셀의 행렬 계산을 한다.
    • mode - 기본값은 maxtrix. matrix 외의 타입 또한 내부적으로는 행렬 곱셈을 적용하는 건 동일하다(고 한다).
    • values - 20개의 숫자(5개의 값*RGBA 4개의 채널)가 나열된 배열. 5개의 값을 해당 픽셀의 RGBA 값과 곱한 값으로 다시 지정한다.
values="r1 r2 r3 r4 r5 g1 g2 g3 g4 g5 b1 b2 b3 b4 b5 a1 a2 a3 a4 a5 " 의 경우

R' = r1*R + r2*G + r3*B + r4*A + r5
G' = g1*R + g2*G + g3*B + g4*A + g5
B' = b1*R + b2*G + b3*B + b4*A + b5
A' = a1*R + a2*G + a3*B + a4*A + a5

 

  • <feComposite> - Porter-Duff 합성 작업 중 하나를 사용하여 두 입력 이미지를 픽셀 단위로 조합한다.
    • in - 필터를 적용할 첫 번째 입력
    • in2 - 필터를 적용할 두 번째 입력 (두 입력을 조합한다.)
    • operator - 어떻게 조합할 것인지에 대한 Operation. over, in, out, atop... 등이 있는데 atop의 경우 in 속성과 in2 속성의 교집합 부분만 나타낸다.

 

 

 

그래서 대체 이 필터 뭘 하는 녀석인데??

 

일단 무작정 삭제해본 뒤 전/후 결과를 비교하면 뭐라도 알게 된다.

 

 

 

svg 필터 삭제 전/후

 

 

 

오오오... 이제야 눈에 뭔가 보인다. 일단 커서에 대한 SVG 필터라는 건 알겠다.

 

삭제 전에는 커서를 가만히 놔뒀을 때 꿈틀거림이 울룩불룩(?)하게 움직였는데, 필터를 삭제하자 그 울룩불룩함의 비밀이 다양한 크기의 원이 움직이는 거였음을 깨달았다. 그러니까, 다양한 크기의 원이 동그란 커서의 테두리 부분에서 움직이게 한 뒤, 각각의 원과 커서의 원이 겹치는 부분만 보이게 하면 마치 검은 원이 우글우글 끓는 것처럼 보이는 거다.

 

또한 움직일 때 늘어지는 끝부분을 보면 SVG 필터를 적용했을 때가 훨씬 둥글고 짧다.

 

 

근데 난 이게 <feComposite> 로 자잘한 원과 기본 원을 합쳐서 나타나는 모양이라 생각하고, <feComposite> 태그를 지워봤는데 그로 인한 차이는 없었다. 사실 저 태그가 왜 존재하는 지도 모를 정도로 전/후 차이가 없다.

 

반면 <feGaussianBlur><feColorMatrix>를 지우면 다시 자잘한 원이 드러난다.

 

으아아아 어렵다

 

 

 

 

https://wsss.tistory.com/1318

 

마우스를 스피드하게 따라다니는 원

See the Pen GSAP 3.0 - SVG Follower (v2) by Tom Miller (@creativeocean) on CodePen. See the Pen GSAP 3.0 - SVG Follower by Tom Miller (@creativeocean) on CodePen. 마우스를 스피드하게 따라다니는 원

wsss.tistory.com