자바스크립트 스톱워치 만들기 — 타이머부터 랩타임까지 완성!

자바스크립트 스톱워치 만들기 — 타이머부터 랩타임까지 완성!
스탑워치 시작 화면

자바스크립트 스톱워치 만들기

이번 포스팅에서는 순수 자바스크립트만 사용해서 스톱워치를 구현해보겠습니다. setIntervalDOM 제어를 활용해 시간을 측정하고, 랩타임 기능까지 추가해 실전형 타이머를 완성해볼 거예요. 그냥 단순히 스탑워치만 만들면 너무 밋밋하니깐 목표 시간을 설정하고, 그것을 맞추도록 하는 게임 형식으로 만들어볼까합니다. 그럼 바로 시작할게요!

1. 기본 HTML 구조 만들기

먼저 화면에 표시될 버튼과 시간 표시 부분을 만들어줍니다.

스톱워치 HTML 코드

저는 시작 화면, 메인 화면으로 나누어서 HTML 코드를 작성했어요. 메인 화면에서 다루어질 내용들은 자바스크립트 코드로 작성될 거라 비어 있네요. 그리고 자바스크립트 파일을 따로 만들어서 연결해서 사용하고 있지만, 하나의 HTML 코드 안에(body 태그 안에) 작성하셔도 무방합니다. 개인적으로 코드가 길어지면 가독성이 떨어진다고 생각해서 저는 나누어서 만들고 있습니다.

💡 팁: 버튼의 id를 명확히 설정해두면 JS에서 쉽게 접근할 수 있습니다. (getElementById, querySelector 등으로 접근하기 쉽습니다.) id 뿐만 아니라 class명으로도 접근이 가능하니 편하신걸로 하시면 될 듯합니다.

2. 시간 계산 로직 구현하기

setInterval()을 사용해 1밀리초마다 시간을 갱신하고, 초, 밀리초 단위로 계산해 표시합니다. 1초부터 60초 사이의 숫자 중에서 목표로 할 숫자를 입력해줍니다. 00.000 형식으로 나타나도록 구조를 잡았고, 시작하기 버튼으로 스탑워치가 시작하고, 정지 버튼을 통해 스탑워치가 정지되도록 구현하였습니다. 정지 되는 순간 바로 목표 시간에 도달했는지 여부를 판단해서 결과가 보여지도록 하였습니다.

// 1~60초 사이의 숫자 입력
const GOAL_TIME = "5";

let chapter;
let sec, mSec;
let timer;

init();

function init() {
    chapter = "start";

    sec = 0;
    mSec = 0;

    timeSec.innerHTML = "00";
    timeMSec.innerHTML = "000";
}

startBtn.addEventListener('click', function() {
    chapter = "main";

    startPage.classList.toggle("hidden");
    mainPage.classList.toggle("hidden");
});

retryBtn.addEventListener('click', function() {
    modal.classList.toggle("hidden");
    
    init();
});

timeStartBtn.addEventListener('click', function() {
    if(timeStartBtn.disabled === false) {
        clearInterval(timer);

        timer = setInterval(setTimer, 1);

        timeStartBtn.disabled = true;
    }
});

timeStopBtn.addEventListener('click', function() {
    clearInterval(timer);

    checkingTime();

    timeStartBtn.disabled = false;
});

function convertGoalTime() {
    let t, s;

    s = String(GOAL_TIME).padStart(2, '0');

    t = s + ".000";

    return t;
}

function checkingTime() {
    secStr = timeSec.innerText;
    mSecStr = timeMSec.innerText;
    let totalTime = secStr + "." + mSecStr;
    let goalTime = convertGoalTime();

    resTime.innerHTML = totalTime;

    if(totalTime == convertGoalTime()) {
        resText.innerHTML = "성공!
축하합니다." } else { resText.innerHTML = "실패!
다시 도전하세요." } modal.classList.toggle("hidden"); } function setTimer() { mSec++; if(mSec < 10) { timeMSec.innerHTML = "00" + mSec; } else if(mSec < 100) { timeMSec.innerHTML = "0" + mSec; } else { timeMSec.innerHTML = mSec; } if(mSec > 999) { sec++; if(sec < 10) { timeSec.innerHTML = "0" + sec; } else { timeSec.innerHTML = sec; } mSec = 0; timeMSec.innerHTML = mSec; } }

시작하기 버튼을 누르면 setInterval()함수를 실행하고, 정지 버튼을 누르면 멈추어야 하기 때문에 setInterval()함수를 timer 변수에 넣고, 시작하기 버튼, 정지 버튼을 누를 경우 clearInterval()함수를 통해서 timer에 들어 있는 함수가 정지 및 제거 해주도록 하였습니다.

convertGoalTime() 함수의 경우에는 목표로 설정한 GOAL_TIME을 00.000 형식으로 리턴해주는 함수입니다.

setTimer()는 1밀리초마다 반복 실행되고, 그 때마다 innerHTML을 활용하여 timeSec 태그 안에 값을 업데이트합니다.

00,000 형태로 구조를 만들다보니 폰트에 따라서 글자의 가로 간격이 맞지 않는 것을 확인할 수 있었습니다. 기능을 구현하는데에는 크게 문제가 없지만, 사용자 입장에서는 숫자 형태가 고정되어 있어야 보기 편하다는 생각을 하였습니다. 그래서 font-variant-numeric: tabular-nums; , font-feature-settings: 'tnum'; 코드를 CSS에 추가해주었습니다. 00.000이 들어가는 태그 css에 추가하시면 됩니다.

3. 스타일링으로 완성하기

단순한 코드지만, 시각적으로 깔끔한 UI를 만들어주면 완성도가 높아집니다. 그냥 단순히 코드를 구현하는 것만 생각한다면 크게 신경을 안써도 되는 부분이지만, 실제로 내가 전체 프로젝트를 만들고, 상용화를 한다면 꼭 신경써야 될 부분이라고 생각합니다. 그러므로 연습용이라도 css도 이것 저것 건들여보면서 공부하면 좋을 것 같습니다.

4. 실행 예시

스톱워치 실행 영상

5. 마무리하며

스톱워치 프로젝트는 단순해 보이지만, 자바스크립트의 핵심인 이벤트 처리, 시간 제어, DOM 갱신을 모두 다루는 훌륭한 예제입니다. 이 코드를 바탕으로 카운트다운 타이머, 공부시간 트래커, 게임 내에서 줄어드는 시간 바, 이벤트 페이지 등으로 확장해보세요.
실제로 제가 사용하고 있는 앱안에서도 이벤트 페이지를 통해 목표 시간에 근접할수록 높은 포인트를 주는 방식으로 활용하고 있습니다.

확장 아이디어: - 로컬 스토리지에 랩타임 기록 저장하기
- 알람 기능 추가해 공부 타이머로 전환하기
- CSS 애니메이션으로 시각적 피드백 주기 - 정지 후에 계속 이어 할 수 있는 기능 추가하기 - 게임 속 타이머 형식 구현해보기

다른 프로젝트도 도전해보세요!

댓글 쓰기

다음 이전