[Project] 포트폴리오 제작기 - 6. (1) 메타볼 애니메이션 구현기 - CSS 편

young_pallete·2022년 12월 14일
3
post-thumbnail

🚦 시작하며

현재 코로나를 걸리다 보니... 원래 아침에 쓰기로 예정이었던 이 글을 지금 쓰게 되네요. 😖
오늘은 실제 프로젝트에 쓰였던, 메타볼 애니메이션을 구현하는 방법을 가져왔어요.

사실, CSS를 이용하면 쉽게 구현 가능한 애니메이션인데요. 저는 몇 가지 한계로 인해, 좀 더 낫다고 판단된 캔버스를 이용하는 방법을 채택했어요. 다만, 결국 문제를 어떻게 접근하느냐를 다각적으로 보여주기 위해 CSS로 구현하는 방법 먼저 써보려 합니다.

여러 방법을 살펴보고, 더 나은 방식을 채택하는 것이 가장 올바른 것 같아요.
이번에 적은 글을 토대로, 누군가에겐 도움이 되었으면 좋겠네요!

🔥 본론

메타볼이란?

일단 메타볼을 모르는 분들을 위해 간단하게 설명하는 것이 좋겠군요.
위키피디아에서는 다음과 같이 정의되어 있습니다.

In computer graphics, metaballs are organic-looking n-dimensional isosurfaces, characterised by their ability to meld together when in close proximity to create single, contiguous objects.

설명만 들으면 이해가 되지 않아요.
그래서 위키피디아의 사진도 첨부해봅니다.

이처럼 메타볼은 가까워지면
1. 서로를 향해 합쳐지고,
2. 모양이 그만큼 커지는 특징을 갖고 있어요.

그럼, 이것을 어떻게 브라우저 상에서 구현할지, 살펴보도록 하죠!

CSS - filter 속성

CSS에서 이를 해결할 수 있는데요.
문제를 해결하기에 가장 쉬운 방법은 바로 CSSfilter 속성을 이용하는 것입니다.

MDN 공식문서에 따르면, filter 속성은 흐림 효과나 색상 변형 등 그래픽 효과를 요소에 적용할 수 있어요.

이때, 우리가 살펴볼 속성은 filter에서 contrastblur에요.
이 두 개의 CSS 함수는 다음과 같은 특징을 갖고 있어요.

  • blur(radius): 지정된 블러의 반경만큼, 주어진 이미지를 흐리게 만들어줍니다. 이를 통해 주변의 흐린부분을 겹쳐, 마치 합쳐지는 듯한 효과를 줄 거에요.
  • contrast(number|percentage): 주어진 이미지의 색채 대비를 조정해줍니다. 이를 강하게 해줌으로써, 우리는 흐린 blur의 효과를 선명하게 해줄 거에요.

어때요. 생각보다 구현 방법에 대한 선수 지식이 적죠?
이것이 CSS로 만드는 메타볼의 장점이에요. 만약 메타볼의 스펙이 간단하게 주어졌다면, 주어진 문제를 손쉽게 해결할 수 있다는 점이죠.

구현

구현 과정을 통해 CSS 메타볼 방법을 익히면서, 동시에 한계를 알려드리려 합니다.
우선 다음과 같은 과정을 통해 진행될 거에요.

  1. HTML 생성
  2. contrast를 컨테이너에 입혀서, 대조를 강하게 주기
  3. 아이템인 메타볼에 filter: blur을 입혀서, 주변 부분을 흐리게 만들기
  4. 애니메이션 입히기

그럼, 준비되셨나요? 시작해보죠!

1. HTML 생성

이 예제를 위해 HTML은 다음과 같이 설정해주세요.

<div id="background">
  <div class="metaball first" />  
  <div class="metaball second" />
</div>

2. 배경에 filter: contrast 입히기

contrast를 먼저 배경에 입혀주어야 하는데요.
저는 제가 가장 좋아하는 색인, 보라색을 입혀주려 합니다.

#background {
  position: relative;
  width: 100vw;
  height: 100vh;
  filter: contrast(100);
  background-color: #752bed;
}

참고로 #752bed는 다음과 같은 색입니다.

과연 결과가 어떻게 나오시나요?
당황스러울 수 있겠지만, 정상입니다. 다음과 같은 파란색이 나와요.

이는 대조 효과 때문인데요. 이 CSS의 가장 큰 단점이기도 합니다.
대조 효과가 항상 강하게 일어나기 때문에, 이로 인한 부수 효과를 컨트롤해주어야 할 필요성이 있어요.

따라서 저는 비슷한 색을 만들기 위해 다음과 같이 설정해주었습니다.

html, body {
  margin: 0;
}

#background {
  position: relative;
  width: 100vw;
  height: 100vh;
  filter: contrast(40);
  background-color: #8a2eff;
}

비슷한 느낌이 나는군요.

3. 아이템인 메타볼에 filter: blur을 입히기

이제 메타볼을 만들 때가 됐습니다.
간단하게 다음과 같이 생성해줄게요.

html, body {
  margin: 0;
}

#background {
  position: relative;
  width: 100vw;
  height: 100vh;
  filter: contrast(40);
  background-color: #8a2eff;
}

.metaball {
  position: absolute;
  left: 300px;
  top: 200px;
  
  width: 100px;
  height: 100px;
  border-radius: 50%;
  -webkit-filter: blur(10px);
}

.first {
  background: yellow;
}

.second {
  background: yellow;
}

핵심을 요약하자면, 결국 배경에 대비를 크게 넣고, blur을 메타볼 효과가 충분히 나도록 넣었습니다.

아직은 하나라서, 둘이 겹쳐 보이지만 실제로는 2개의 원이 생성된 것입니다!
이때, 단점이 보이시나요? 아까 언급했던, 색 조정에 대한 문제가 발생합니다.

그렇지만 저 분홍색은 blur 효과를 대비를 세게 해서 나타난 현상이라, 처리하기가 꽤나 곤란해 보여요. 이것이 제가 CSS로 만드는 메타볼을 포기한 이유입니다. 😭

그렇지만 일단 끝은 내보아야죠.
이제 애니메이션만 제대로 넣으면 되겠죠?

4. 애니메이션 입히기

메타볼효과가 정말 나는지, 좌우로 움직이도록 설정을 해줍니다.

.first {
  background: yellow;
  animation: move-first infinite 15s both;
}

.second {
  background: yellow;
  animation: move-second infinite 15s both;
}

@keyframes move-first {
  0% {
    transform: translateX(0);
  }
  
  50% {
    transform: translateX(200px);
  }
  
  100% {
    transform: translateX(0);
  }
}

@keyframes move-second {
  0% {
    transform: translateX(200px);
  }
  
  50% {
    transform: translateX(0px);
  }
  
  100% {
    transform: translateX(200px);
  }
}

메타볼 애니메이션을 성공적으로 구현했어요.

  1. 서로의 엘리먼트(원자)가 합쳐져 살짝 커지기도 하고
  2. 합쳐질 때 자연스러운 특유의 애니메이션이 나오죠.

하지만, 위에서 언급했던, 색에 대한 조작이 어렵다는 점과, 또한 결국 엘리먼트를 조작하는 것이기에 최적화 관점에서 아무리 trasition을 쓰더라도 여러 메타볼을 생성할 것을 고려하면 찝찝한 점은 들어요 😖

🚀 마치며

결국 CSS로 메타볼을 구현하는 방법은 포기했습니다.
따라서 저는 캔버스로 메타볼을 구현했는데요.

다음에 살펴볼 것은 1번과 2번의 기능을 모두 가진 메타볼의 애니메이션을 그리는 법과, 그 한계점에 대해서 이야기를 해볼까 합니다.

포트폴리오가 끝난 시점이 꽤 됐는데, 워낙 하고 있는 공부와 일들이 많아서 좀 버벅이긴 하네요. 그렇지만 꾸준히 일정을 잡고 포스팅하려 노력 중이네요.

약 2달만에 다시 만난 메타볼 구현 방법은 꽤나 낯설고 새로운 한편, 즐거웠네요. 이상! 🙆🏻

profile
People are scared of falling to the bottom but born from there. What they've lost is nth. 😉

0개의 댓글