본문 바로가기
창고(2021년 이전)

JS시계 API - flip clock을 이용한 출퇴근 관리

by 측면삼각근 2019. 10. 29.
728x90
반응형

이 글은 앞서 종료된 프로젝트의 사용 API와 코드 정리글입니다. :-D

프로젝트 구현이 끝나가고 간단한 시계가 필요하던 차에 유투브 Online tutorials 채널에서 flip clock api를 보게되었다.단순한 시계는 굳이 이것을 사용하지 않고 javascript 만으로도 구현이 가능하고, 구글에 오픈되어있는 소스도 많지만 flip clock 은 시계 뿐만아니라 타이머, 달력 등등으로도 조정할수 있고, 디자인 역시 (이미)완성형이므로 이를 활용게되었다. ( 하지만 이는 동시에 크게 수정이 불가능하다는 뜻이기도 하다! 색상외에 상세한 UI를 변경하려 하는 즉시 배치가 깨지기 시작한다..ㅠ)

- 화면의 우측 상단의 시간 카운팅 flip clock

가장 기본적인(현재 날짜로서의) 활용법은 Online tutorials 유투브 에 매우 매우 매우 매우 상세히 나와있다.

clickClock 깃허브 에서 이를 받아 경로에 넣고 사용하는 방식이다.

Demo와 Documents 또한 추가적인 옵션의 사용법을 공식 사이트에서 친절히(?) 안내하고있다.
여러 옵션을 사용할 수 있는데, 현재 날짜를 띄워주는 다소 정적인 방식으로 활용할 수 도 있고, 현재 시간과 초를 띄워줄 수 도있다.
시간과 초만 설정할수도, 날짜인데 달과 월만 설정할수도 있다.

간단한 설정으로 여러가지 활용이 가능하다.


지난 프로젝트에서 내가 활용했던 방식은 카운터 였는데, 사원이 출근 버튼을 누르면 그때부터 시간이 counting 되는 방식이다. 제이쿼리로 활용하였다.

구현 시간이 부족해 웹소켓까지 활용하지 못했지만, 사용자에게는 실시간으로 작동되는 것 처럼 보이기 위해 크게 두가지로 활용하였다.

  1.  작동을 시킬것인가? 멈춰있을 것인가?
  2.  작동 시점은 언제부터인가? (현재 시점부터 인가 or DB에 저장되어 있는 시점부터 인가) 

 

구현 로직은 다음과 같다. (간단)

  1. DB에 로그인한 사원의 출근시간이 기록되어 있지 않다면, 작동이 멈추어 있을것(초기값 00:00:00).
  2. 출근 버튼을 눌렀을 시 flip clock counting을 작동시켜 시작되고, DB에 출근시간을 기록
  3. DB에 로그인한 사원의 출근 시간이 이미 존재한다면, 출근시간부터의 counting 을 작동시킴
  4. DB에 로그인한 사원의 퇴근 시간이 존재한다면, flip clock counting 을 멈춤

 


 

구현 소스코드 - TOPBAR : flip clock 기본값 설정

	var clock;
	var watSub=0;

	var setDate = new Date();
	
	clock = new FlipClock($('.clock'), {
		clockFace: 'HourlyCounter',
		autoStart: false,
		countdown: false,
		callbacks: {}
		});
		clock.setTime(0);
	
		$.ajax({
			url:"getMychulgun.do",
			dataType:"json",
			success:function(data){
				// https://github.com/objectivehtml/FlipClock/issues/258
				// FlipClock counts down too fast - 참조
				// 너무 빨리 카운팅 되는 문제가 있었음
				// Count up 코드 참조
				// https://stackoverflow.com/questions/26599615/flipclock-count-up-from-a-particular-date
				
				if(data!=null){
					setDate = data.ATTEND;
					setDate = new Date(Date.parse(setDate));
					if(data.GOHOME ==null){
						var currentDate = new Date();
					}else{
						var currentDate = data.GOHOME;
						currentDate = new Date(Date.parse(currentDate));
					}					
						var diff = (currentDate.getTime()/1000) - (setDate.getTime()/1000) ;
						if(diff<0){
							diff = 0;
						}
						watSub = diff;
						clock.setTime(diff);
						
					if(data.GOHOME ==null){
						clock.start();
					}
				}
			}
		});

clockFace는 HourlyCounter로 최대단위가 (시간)인 counter 를 사용하였으며, autostart와 countdown 옵션을 끄고, 혹시몰라 setTime(0);을 설정 했던 듯하다.

getMychulgun.do(스프링 framework의 url mapping)의 해당 Controller로 이동해 DB에서 해당 사원의 출퇴근 시간을 가져왔고, 만일 해당 사원의 data가 존재한다면 현재시간으로 선언했던 setDate 변수를 해당 데이터로 재선언한다.(시작 시간 설정)

만일 퇴근시간 또한 존재한다면, currentDate 변수를 해당 data로 선언한다.
존재하지 않는다면, new Date()선언을 통해 현재시간으로 선언한다.

또한 autostart 와 countdown옵션을 모두 false로 놓았기에, 퇴근시간이 존재하지 않을때에만 카운팅을 시작한다.(clock.start();)

이때 이 차이(diff)를 계산해 setTime메소드로 차이를 넣어 setTime(diff)로 counting 시간을 설정한다.
이때 지금도 잘 알수없는 에러가 발생하는데, 코드 주석으로도 달려있다. 단순히 currentDate - setDate로 diff를 설정하여 실행시키면, 언뜻보기엔 정상적으로 작동하는 듯 보이나, 실제시간 0.5초에 1초가 counting되는 문제가 발생한다.

물론 언뜻보기엔 티가 안나긴 하지만, 장시간 페이지에 머물러있다가 페이지 이동시에 counting 되는 시간이 refresh되면서 시간 차이가 굉장히 많이나는 것이 눈에 띄게 되는것이다.

flipclock의 깃허브 issues 에서 해당 문제에 대하여 사람들이 의논하고 해결코드가 게시되어 있었다.

다음은 이러한 시계 기본 설정(topbar 파일)을 완료 후

flip clock 작동 코드

홈(home)파일의 출,퇴근 버튼 내용의 구현내용이다. 지옥의 작명 Watsub은 topbar 파일(위의 소스코드) 에서 선언했던 전역수이다. 페이지 로딩시 현재 시간과 DB의 출근시간의 차를 계산하여 선언한 변수이다.

$(document).on('click','#commute',function(){
	$.ajax({
      url:"chulgun.do",
      type:"post",
      success:function(data){
        if(data=="fail"){
            alert("출근 등록에 실패했습니다.\n관리자에게 문의해주세요!");
        }else{
          $("#commute").hide();
          $(".goHome").fadeIn(1000);
          $(".chulgun").text("출근 : "+data);
          $(".zipgalle").text("퇴근 : 아직 퇴근 시간이 기록되지 않았어요!");
          clock.start();
        }
	  }
	});
});

$(document).on('click','.goHome',function(){
	var result ="";
	var check = false;
	if(watSub<32400){
		check = confirm("아직 근무 시간이 남아있습니다.\n정말로 퇴근하시겠습니까?");
		$("#resultArea").css('color','red');
		result = "조기퇴근";
	}else{
      	check = confirm("정말로 퇴근하시겠습니까?");
      	result = "정상퇴근";
		$("#resultArea").css('color','green');
	}
	
    if (check){
		$.ajax({
      		url:"goHome.do",
      		dataType:"json",
  				success:function(data){
					if(data.result=="fail"){
						alert("퇴근등록에 실패했습니다.\n관리자에게 문의해주세요!");
					}else{
						$(".goHome").fadeOut(1000);
						$(".zipgalle").text("퇴근 : "+data.map.GOHOME);
						setTimeout(function(){
                          $("#resultArea").text(result);
                          }, 980);
						clock.stop();
					}
				}
			});
		}
});

$(document).ready(function(){
	setTimeout(function(){
      if(watSub<32400 && "${map.GOHOME}"!=""){
        $("#resultArea").css('color','red');
        $("#resultArea").text("조기퇴근");
      }else if(watSub>=32400 && "${map.GOHOME}"!=""){
		$("#resultArea").css('color','green');
		$("#resultArea").text("정상퇴근");
	}
}, 100);
});

출퇴근 시간 등록 ajax 및 실패 및 버튼 작동에 따른 alert 설정과 제이쿼리를 이용한 css설정까지 모두 들어가있어 코드가 다소 지저분 해 보일 수 있다.

동작하는 코드의 내용은

  1. DB에 퇴근 data(GOHOME)이 존재한다면,  전역변수의 값을 할당해주고 시계동작을 (시각적으로)멈춘다. 
  2. DB에 출근 data가 존재하지 않을 시 출근 버튼만이 보이며, DB에 출근 시간을 업로드 후 이 버튼을 클릭시 시계 동작을(시각적으로) 시작한다.

나는 CSS코드에 모두 transition을 걸어놓아 setTimeout 을 통해 적절히 버튼 등장 시간을 조정을 하였다.
(그렇지 않으면 transition 옵션 으로 인해 ui가 상당히 불안정해 보였음)

 


 

시계의 default 크기는 굉장히 크다.

아래의 CSS코드로 줄일수 있다.

	.timer {
	    zoom: 0.4;
	    -moz-transform: scale(0.4);
	}

 


아쉬운점

  1. 굉장히 간단한 API였음에도 마주했던 에러들은 아직도 왜그런지 모르겠다..
  2. 이시국에 제이쿼리를 사용하여 구현하였다는것이 굉장히 아쉽다. 시간이 날 때 js만을 사용하여 구현해볼 시간이 있었으면 좋겠다( 하지만 그럴 시간이 있을지는 잘 모르겠다. )
  3. ES6와 함수형 프로그래밍을 (얕게나마)학습하니 굉장히 아쉬운 부분들이 많이보인다.
  4. 하지만 아직도 출퇴근시간을 전역으로 선언하는 것 말고는 다른 방법을 잘 모르겠다.
    (객체로 선언해야했나? 아니면, 단순히 '전역변수'라는 것을 회피하기 위해서는 클로져 패턴을 활용하여도 괜찮을 듯 하다.
    하지만 재선언 될 일도 없는데, 오로지 전역변수에 대한 회피로서의 추가 코딩이 의미가 있는가?
    조금더 고민해 볼 상황인것같다.)

지금 시점에서는 여러가지 아쉬움이 보이지만, 당시 지식으로는 나름대로 최선의 방법이였던것같다!

시간이 될 때 다시 코딩할 수 있었으면 한다.

반응형