본문 바로가기
Javascript

여러 개의 이미지 파일들을 로테이션 해서 보여주기 - Shuffle 효과

by 즐코딩 2022. 12. 20.
반응형

최근에 개인프로젝트로 간단한 웹기반 애플리케이션을 만들었습니다. 크리스마스 시즌이기도 해서 신년 인사들을 메신저로 많이 주고받을 텐데요, 그때 지인들에게 보내주면 좋겠다는 생각이 들어서 간단하게 즐길 수 있는 app을 만들어보았습니다. 막상 직접 프로젝트를 진행하다보니 디테일에 점점 욕심이 났지만, 재미로 하는 작업이라 그냥 심플한 수준에서 마무리를 했습니다.

MBTI 이상형 여친 찾기 / 남친 찾기


제가 이번에 만들어 본 애플리케이션입니다.
뭔가 거창한 걸 만들 시간은 없고해서 짧게 진행할 수 있는 프로젝트로 선정을 해봤습니다. 연말, 크리스마스에는 뭐니뭐니 해도 옆구리 허전한 사람들에게는 절대적으로 애인이 필요하겠죠?^^;

MBTI-이상형-여친-찾기-MBTI-이상형-남친-잦기
MBTI 이상형 여친 찾기 / MBTI 이상형 남친 잦기



직접 해보는 게 가장 큰 공부


역시나 그 동안 공부해왔던 내용을 바탕으로 셀프 테스트도 해볼겸, 직접 구상하고 디자인하고 개발까지 진행하면서 이번에 큰 공부가 된 것 같습니다. 마무리에 검색엔진 등록 애드센스 광고를 붙여 오픈하기까지 일주일 정도 걸렸던 것 같습니다.

이번에 새롭게 공부가 된 것들

이미지를 로테이션 해보자


테스트 마지막 단계에서, AI가 여친, 남친을 매칭해주는 화면 연출을 어떻게 하면 좋을까? 하는 것이 가장 큰 고민거리 였습니다. 아래 이미지처럼 포토샵을 이용해서 Animationed GIF 파일을 만들면 가장 손쉬울 텐데, 이런 방식은 남친, 여친 2개의 결과물을 만들어야 하고, 또 롤링이 되는 시간 조절 등이 발생하면 반복적으로 포토샵 작업을 해줘야 한다는 단점이 있습니다. 그래서 공부도 할겸 Javascript 코드로 구현해보기로 했습니다.

포토샵에서 만든 Animated GIF 예시


setTimeout / clearTimeout 사용


이미지 로테이션을 구현하는 방법으로는 setTimeout을 사용해보기로 했습니다. 우선은 무식한 방법으로 사용될 파일명들을 배열에 담아 변수로 설정했습니다. 그리고 불러다 쓰는 거죠 뭐. 작성된 코드는 다음과 같습니다.

const imgNames = ["img1", "img2", "img3", "img4", "img5", "img6", "img7"];

let obTimeOut; // clearTimeout() 함수를 이용하여 Timeout 을 취소하기위해 사용됨
const ObjectArray = new Array();
for (i = 0; i < imgNames.length; i++) {
        ObjectArray[i] = imgNames[i + 1] + ".png"; //나중에 확장자 jpg 경우 등에 활용을 위해서..
      }
let nObjectCnt = 0;

function ShowDefaultRotate() {  // 스스로 자신을 호출하는 재귀함수(Recursive Function) 
        nObjectCnt++;
        if (nObjectCnt < ObjectArray.length) {
          document.querySelector("#imgshuffle").setAttribute("src", "imgs/" + ObjectArray[nObjectCnt]);
          obTimeOut = setTimeout("ShowDefaultRotate()", 200); // 0.2초 후에 자기자신을 호출
        } else {
          clearTimeout(obTimeOut); // 배열의 갯수만큼 반복하여 변환시킨 후에는 Timeout 을 중지시킨다
          nObjectCnt = 0; //끝내기 전 카운트 초기화 -> 반복하는 사람들을 위해 필요
        }
      }
      
function startAnimation() {
        obTimeOut = window.setTimeout(ShowDefaultRotate, 200); // 윈도우 로드 후 0.2초 후에 반복함수를 호출합니다.
      }


코드가 길어서 조금 복잡해보이긴 하지만, 자세히 보면 별 건 없습니다. 어디에선가 strartAnimation() 함수를 호출하게 되면, obTimeOut에 setTimeout(ShowDefaulRoate, 200)을 실행해준 결과를 넣어줘 멈추게 되는 거죠.

ShowDefaultRoate(), 즉 이미지 로테이션은 배열 안에 담긴 이미지의 개수 만큼 0.2초 마다 반복된 후, clearTimeout을 호출하게 됩니다.

예전에 공부했던 내용이긴 하지만 가물가물해서 이번 작업하면서 다시 잘 찾아 보고 이 참에 정리했습니다.

그러나 현실은 다르다


로컬 환경에서 돌려보니 동작이 잘 되길래, 아싸~!! 하고 쾌재를 부르면서 서버에 Deploy했습니다. 그... 그런데, 서버에 올라간 상태에서는 제대로 동작을 하지 않는 것이었습니다!! 이미지 로테이션이 나타나지 않거나 버벅 거리는 현상이 나타났습니다. 역시 프로그래밍 개발이 한방에 되면 이상한 거겠죠?

왜 그럴까?


왜 이런 현상이 일어나는 것일까요? 서버와 로컬의 다른 점은 무엇일까요? 곰곰히 생각해보다가 무릎을 탁 쳤습니다.
로컬에서는 로테이션할 이미지를 브라우저가 모두 가지고 있었지만(혹은 로드가 개빠르겠지만), 서버에 접속한 브라우저로서는 해당 이미지들을 내려 받기 위한 시간이 필요해지는 것이죠. 필요한 이미지를 내려 받기도 전에 setTimeout / clearTimeout이 작동을 하게 된 것입니다.

필요한 이미지를 먼저 내려 받기


그렇다면 로테이션(셔플)에 필요한 이미지를 미리 내려 받아 두면 가능하지 않을까? 하는 생각에 이르렀습니다. 동기/비동기 방식으로 해결하기에는 아직 좀 더 공부가 필요한 것 같아서, 일단 결과물을 빨리 보고 싶은 마음에 CSS로 아주 쉬운 치트키를 사용해보기로 했습니다. CSS로는 과연 어떻게 하면 될까요?

CSS 가상 선택자로 필요 이미지 내려 받고 숨겨두기


단순 무식하지만, 첫 공부라 생각하고 일단 가장 간단한 방법으로 시도해보았습니다.

body::after {
  /* 이미지 미리 로딩하기 */
  position: absolute; 
  width: 0;
  height: 0;
  overflow: hidden;
  z-index: -1;
  content: url(imgs/img01.png) url(imgs/img02.png) url(imgs/img03.png) url(imgs/img04.png) url(imgs/img05.png) url(imgs/img06.png) url(imgs/img07.png);
}

body::after로 가상선택자를 줘서 body가 로딩된 이후에 position 붕 띄우고, 크기는 가로세로 0으로 지정, 혹시나 넘칠 것에 대비해서 overflow도 감췄습니다. 혹시 몰라 z-index를 이용해서 화면 제일 뒤로 숨겼습니다. 이렇게 해두면 브라우저는 저 이미지들을 미리 다운로드 받아놓게 되어, 로테이션을 동작시키는 startAnimaion() 함수가 동작할 때, 잘 동작하게 됩니다.

CSS를 이용해서 이렇게 치트키처럼 사용하는 방식은 이번 작업을 진행해보면서 처음 알게 되었습니다. 역시나 대단한 사람들!

그리고 중요했던 경험, 카운터 변수 초기화


코딩 개발을 직접 해본다는 것은, 눈으로 보고 머리로 생각할 때 와는 전혀 다른 이슈들이 많이 발생하는 것 같습니다. 오타로 인한 오작동은 물론 기본으로 쏟아져 내리구요, 해당 프로그램을 브라우저 새로고침 없이 반복적으로 실행하려면 프로그램 안에 생성해둔 counter 변수들을 다시 초기화 해둬야 한다는 중요한 사실을 경험하게 되었습니다. 이거 하나에 눈을 뜨고 나니, 상태에 변화를 주는 값들은 함수 종료 전에 다시 한번 초기화 해두는 안목이 생기더라구요.
아주 큰 수확으로 다가오게 된 경험이었습니다.

카운트-변수-초기화의-중요성
카운트 변수 초기화의 중요성


마치며


기획 구상을 마치고, 디자인 자료들도 준비를 해둔 후 코딩 개발을 진행하는 과정은 2박 3일 정도 몰입해서 진행을 했던 것 같습니다. 시간 가는 줄 모르게 코드 짜고 테스트하고 했더랬습니다. 지금 이 나이에 다시 이렇게 집중하고 몰입할 수 있는 대상이 있다는 게 무척 행복한 느낌입니다. 성장하는 즐거움도 크구요.

그리고 '개발자' 역할을 직접 해보면서, 역시나 개발자에게는 좋은 기획자와 좋은 디자이너가 앞단에 팀으로서 필요하구나 하는 당연한 사실도 크게 다가왔습니다. 개발하다 말고, 기획 내용 변경하고... 개발하다 말고 포토샵 열어서 디자인하고... 이거 엄청 호흡과 흐름을 깎아 먹는 일이 되더라구요.

IT프로젝트는 역시나, 팀 프로젝트가 정답입니다.


MBTI 이상형 찾기 결과물 소개는 다음 포스팅에서.... app.kincoding.com


즐거운 코딩생활, 즐코딩.
KINcoding.




반응형

댓글