본문 바로가기

개발/FE

[Canvas] 점도 있는 물방울이 뚝뚝

아이디어가 정말 신기하다. 영어로 blobbing shape 라고도 표현하는데, canvas에 그리는 원이 점도 있는 액체처럼 보이는 효과를 위해 사용된다. 기본 개념은 간단한다. 다음의 두 원을 보자.

이 둘에 블러 효과를 주면 다음처럼 된다.

filter: blur(15px);

 

여기에 constrast라는 값을 준다. 말 그대로 대비를 강하게 주는 건데 블러가 적용된 채로 constart를 주면?

filter: contrast(20);

붙는다!

 

간단한 원리를 짚고 넘어가자. 블러 효과에 대비 강하게 줄수록, 블러 처리가 강하게 들어간 곳은 안 보이게 되고(투명도0) 블러 처리가 된 채로 겹치게 된 부분은 불투명도가 높아지는 대비 효과를 통해서 두 엔티티가 끈적하게 붙는다.

 

css로 간단하게 구현했지만 js의 세밀한 조절을 위해 html 태그를 통해 이 옵션을 줄 수가 있다. 아이콘 때 주로 접했던 svg 태그가 사용되며 그 안에 여러 옵션 태그 등을 통해 값을 조작한다. css에서 filter 프로퍼티를 사용했던 것처럼 태그에서도 filter를 사용하며 그 자식 태그로 faGaussianBlur라는 태그를 통해 값을 준다.

<svg>
   <defs>
     <filter id="gooey">
       <feGaussianBlur stdDeviation="40" in="SourceGraphic" result="blur" />
      </filter>
   </defs>
 </svg>

deviation은 '편차'라는 의미로 실제 조작할 값이다. in="SourceGraphic"은 해당 필터가 적용될 곳에서 그래픽 요소를 사용한다는 의미다. result로 지정하는 값은 다른 태그에서 접근할 수 있는 별칭이라고 생각하면 된다. 이렇게 하면 id 값으로 필터에 접근 가능하며 css에 적용할 수 있다.

canvas {
   filter: url("#gooey");
}

 

블러를 적용했으니 constrast를 적용할 차례. 정확히는 알파 채널에 대한 조절을 해야 한다. feColorMatrix를 통해 행렬로 조절하게 된다.

<feColorMatrix
    in="blur"
    mode="matrix"
    values="1 0 0 0 0  0 1 0 0 0  0 0 1 0 0  0 0 0 100 -23"
/>

앞서 적용한 블러 필터를 받기 때문에 in 속성에 "blur"를 넣어준다. values를 살펴보면 rgb 값은 건드리지 않을 것이므로 순서대로 1이 들어가는 걸 볼 수 있다. 행렬 연산 순서가 중요한데 1x4 행렬은 4x5와 곱셈할 수 있다. 그래서 values에 있는 값은 rgb는 건드리지 않고 알파 채널만 건드린다. 100 값이 들어간 위치는 알파 채널, -23들어간 위치는 알파 오프셋이다. 오프셋은 적용된 알파값에 더하고 뺄 수 있는 상수 값. 아래 예제는 dat.GUI를 통해서 각 수치를 조절한다. 속도 조절도 넣었다.

 

'개발 > FE' 카테고리의 다른 글

하버사인 공식  (0) 2026.02.20
[Canvas] willReadFrequently  (0) 2026.01.19