예전에 Muzli에 소개된 사이트에서 이미지에 CSS image-rendering 속성을 사용해 Pixel Mosaic 애니메이션을 적용한 것을 보며, 이미지를 지연 로딩(lazy loading)할 때에 효과적으로 적용할 수 있겠다 싶어 따라 해봤습니다.
원본 사이트를 따로 메모해 두지 않아 아쉽게도 기억을 끄집어내며 프로타입을 만들었네요.
이미지
640X360 크기의 원본 이미지
100X56 크기의 이미지 (동일 비율로 축소)
50X28 크기의 이미지 (동일 비율로 축소)
애니메이션 명세
모든 이미지는 원본 이미지 크기인 640X360로 노출된다.
CSS image-rendering: pixelated 속성을 적용한다.
50X28 → 100X56 → 640X360 순으로 노출된다.
각 이미지는 0.5초 딜레이 되어 노출된다.
결과
픽셀에서 점차 작은 픽셀로 촘촘해지면서 선명해지도록 해보고 싶었으나 단순 HTML/CSS 상으로 구현하기에는 이미지를 크기별로 리사이징 해야 하는 개수가 많아져서 3단계로만 진행했습니다.
이미지의 크기 차이가 크지 않아야 자연스럽고 예뻤으며 해외사이트에서는 정지 이미지로만 이루어졌는데 오히려 gif와 같은 동적인 애니메이션에 활용하니 효과가 극대화되는 것 같습니다.
위 프로토타입 구현 방식의 한계로는
정적인 페이지에만 제한적으로 활용할 수 있을 듯합니다.
(이미지의 사이즈가 고정적이어야 하고, 사이즈별로 이미지가 준비되어 있어야 하는 등)이미지 크기는 GD 라이브러리 등을 이용하여 서버에서 미리 사이즈별로 리사이징 하여 저장해 두면 데이터들이 달라지는 페이지에도 적용해 볼 수 있을 것 같습니다.
하지만 불러오는 이미지 개수가 많아지고, 작은 이미지 크기라 할지라도 불러오는 데 시간이 걸리기 때문에 지연 로딩(lazy loading)에 대한 효과가 없는 단순 인터랙션이라고만 생각합니다.
base64 인코딩으로 가장 작은 이미지 크기를 html에 심으면 되지 않을까? 싶기도….
가설 & 시도해 보기
Lazy Loading은 화면 영역에 들어왔을 때 스켈레톤과 같은 효과 없이 이미지 로딩이 늦게 이루어지더라도 모자이크 효과가 보인다면 이용자가 지루해하지 않고 하나의 콘셉트 효과로 생각하지 않을까?
특정 class를 가진 원본 이미지에 Canvas를 활용해 Pixel Mosaic 효과를 구현한다면 사이즈마다 따로 이미지를 저장하지 않고 하나의 이미지로 문서 내의 여러 이미지에 쉽게 적용할 수 있지 않을까?
위와 같은 생각을 가지고 기본 Javascript 문법 위주만 알고 있는 저는 Chat GPT의 도움을 받기로 하고 여러 번 시도해 봤는데 Canvas를 활용한 원하는 작동 코드를 만들어 주지 않아 실패했습니다.
Chat GPT는 모자이크를 가우시안 블러 효과로 보여주거나 이미지를 실제 모자이크 효과를 적용하는 것처럼 무언가 로직을 사용해 픽셀을 구현했으나, 구글을 검색해 보니 Canvas에 imageSmoothingEnabled = false 속성만 주면, CSS image-rendering: pixelated와 같이 쉽게 구현할 수 있는 것 같았습니다.
따라서 고정된 폭에 작은 사이즈로 축소한 이미지를 원본 크기의 Canvas에 확대하는 식으로 효과를 구현하도록 주문했으나 계속 잘 안돼서 포기를….
마무리
원래 이미지를 매끄럽게 보여주기 위한 방식으로 개발된 속성인데 이를 이용해 과거 픽셀 모자이크 효과로 활용했다는 발상에 감탄했습니다.
보통은 auto로 두고 사용할 일이 없지만, 고전 픽셀 스타일이나 저해상도의 QR 코드, 바코드 이미지에 image-rendering: pixelated를 사용한다면 용량이 적은 저해상도 이미지로 해상도가 높은 모니터에 화질열화처럼 안 보이고 효과적으로 보여줄 수 있겠다 싶었습니다.
역시 사람은 아는 게 많아야 여기저기 활용할 수 있다고 생각하며 다시 한번 Javascript와 Canvas를 공부해야 할 필요성을 느낍니다.