React에서 초시계를 만듭니다.js 및 CSS

예전에 저는 수석 엔지니어 자리를 면접할 때 vanilla JS로 시뮬레이션 시계를 만드는 도전에 부딪혔습니다.실시간이었어나는 이 연습을 완성하는 데 한 시간도 안 걸렸지만, 15분도 안 되는 시간에 완성했다.나는 이전에 시계에 코드를 만들어 본 적이 없어서 놀랐다.최근에 나는 이 연습을 계속하고 싶지만 더 복잡한 일을 해야 하며 심지어는 상호작용을 해야 한다는 것을 알게 되었다.
나는 초시계가 가장 적합하다고 생각한다.수학은 기초적이지만, 어떤 개념들은 새것이고, 심지어는 까다로울 수도 있다.

TLDR: 리액트와 CSS로 초시계를 만들었는데 너무 귀여워요.이리 와봐:


만약 네가 아직도 여기에 있다면, 우리 이 프로젝트를 좀 보자.

기능 요구 사항


어떤 프로그램을 시작할 때 가장 먼저 고려해야 할 것은 이 일을 도대체 무엇을 해야 하는가 하는 것이다.그것의 기능은 무엇입니까?인터넷에서 초시계 기능에 대한 지식을 몇 가지 훑어본 후(보통 사람들이 초시계만 자주 사용하기 때문에?)내가 결정한 나의 기본적인 요구는 다음과 같다.

  • 시작 시간과 "지금"사이의 밀리초 수를 추적하여 타이머를 시작합니다.

  • 임의의 도넛 수를 표시하고, 임의의 시간 스탬프 목록을 저장하기만 하면 됩니다.

  • 타이머를 중지합니다.

  • 중지된 타이머를 복원합니다.

  • 타이머를 0으로 재설정합니다.
  • 이러한 요구 사항을 고려하여 API는 다음과 같습니다.
    const Stopwatch = () => {
      const start = () => {} // also restarts
      const mark = () => {}
      const stop = () => {}
      const reset = () => {}
    }
    

    사용자 인터페이스


    다음 단계에서는 UI 기능을 고려해야 합니다.사용자는 무엇을 볼 수 있습니까?그녀는 어떻게 응용 프로그램과 상호작용할 것입니까?우리의 기능 요구에 따라 나는 내가 필요로 하는 것을 안다.

  • 시간을 거쳐 숫자를 읽다.
  • 표지판의 목록.

  • 타이머 시작, 정지, 복구, 재설정, 태그 링 수를 제어합니다.
  • 이러한 시각적 수요에서 우리는 우리가 필요로 하는 기본 구성 요소를 추측해 낼 수 있다.

    다이얼


    순수한 시각 효과를 얻기 위해 나는 지나간 시간을 아날로그 초시계로 표시하고 바늘이 중심을 둘러싸고 분, 초, 밀리초를 회전시킨다.
  • 손목시계 바늘은 매 바늘마다 분, 초, 밀리초를 표시한다.이것들은 일반적인 Hand 구성 요소로 추상화되었다.손마다 공통된 스타일링이 있지만 색깔에 따라 다를 수 있다.주어진 시간에 모든 손은 그 값에 따라 회전한다. 우리는 하나의 내연 스타일을 통해 이 내연 스타일은 변환 규칙을 적용하고 translateX(-50%) 도구를 통해 rotate를 적용되는 값으로 설정할 것이다.

  • 기호: 초(1/60)마다 옅은 회색 기호를 한 바퀴 간격으로 하고 5초 간격의 기호는 깊을수록 두껍고 15초 간격의 기호는 깊을수록 두껍다.나는 이런 것들을 만들기 위해 제로 HTML/JSX 요소를 사용했다.그것들은 CSS에서 시계 표면value에 적용되는 위조 원소의 원추형 점차적인 변화를 사용하여 만들어진 것이다.물론 이 점은 처음에는 좀 까다롭지만 수학은 결국 매우 간단하다.
  • 1초 간격: 동그라미 내 360도를 1분 내 60초로 나누기 = 1.67도마다 기호
  • 5초 간격: 360/12 = 30도당
  • 15초 간격: 360/4 = 90도당
  • 따라서 내 CSS에는 3개의 반복되는 테이퍼 그래디언트가 있습니다.
    background-image: repeating-conic-gradient(
      from 359deg,
      #555 0 2deg, transparent 2deg 90deg      
    ), repeating-conic-gradient(
      from 359.5deg,
      #555 0 1deg, transparent 1deg 30deg      
    ), repeating-conic-gradient(
      from 359.75deg,
      #ccc 0 .5deg, transparent .5deg 6deg      
    );
    
    이러한 결과는 다음과 같습니다.

    그런 다음 끝을 제외하고 모든 그래디언트를 숨기거나 표시하는 마스크가 필요합니다.
    mask-image: radial-gradient(
      circle at center,
      transparent 66%,
      #fff 66.1%
    );
    
    결과:

    컨트롤


    나는 우리의 제어를 표시하기 위해 단추 표시줄이 필요하다

  • 시동 버튼 시동 타이머.타이머가 실행될 때, 이 단추는 '링' 단추로 이중 작용을 한다.

  • 타이머의 정지 단추를 정지합니다.

  • 초시계 구성 요소를 원래 '제로' 상태로 완전히 재설정합니다.
  • 숫자 읽기


    아날로그 시계를 제외하고 지나간 시간을 표시하기 위해서, 나는 숫자 읽기 (MM: SS: SS 형식) 를 추가하기로 결정했다. 왜냐하면 그것은 더 읽을 수 있기 때문이다.이상하게도, 이것은 우리 코드의 가장 중요한 부분이다. 밀리초 단위의 이미 사용된 시간을 1분, 1초, 나머지 밀리초로 바꾸는 것이다.
    나는 단지 1분 1초를 얻을 수 있을 뿐, 여수가 없고, 0보다 적지 않다.나는 응용::before을 통해 전자는 항상 가장 가까운 정수로 반올림하고 후자는 응용Math.floor(value)을 통해 0보다 작은 값을 0으로 바꾼다.편리한 함수로 저장하고 유용한 상수를 정의했습니다.
    const getNumOrZero = num => Math.floor(Math.max(0, num))
    const ONE_SECOND_MS = 1000
    const ONE_MINUTE_MS = ONE_SECOND_MS * 60
    

    꼬박 1분


    현재, 나는 1분의 값을 얻기 위해 총Math.max(0, value)밀리초를 1분의 밀리초수elapsed로 간단하게 나누고, 나머지 수가 없는 1분ONE_MINUTE_MSviaMath.floor를 반올림할 수 있다.
    const wholeMinutesValue = getNumOrZero(elapsed / ONE_MINUTE_MS)
    
    밀리초 후에 나는 이 값이 필요하기 때문에 간단하게 그것을 곱할 수 있다getNumOrZero():
    const wholeMinutesInMs = wholeMinutesValue * ONE_MINUTE_MS
    

    초내


    그리고 나는 같은 일을 해서 1초를 얻는다.나는 전체 ONE_MINUTE_MS 밀리초를 위에서 계산한 elapsedwholeMinutesInMs (1초 동안의 밀리초) 로 나누었다.이것이 바로 1분을 빼고 남은 일초수다.
    const wholeSecondsValue = getNumOrZero((elapsed - wholeMinutesInMs) / ONE_SECOND_MS)
    const wholeSecondsInMs = wholeSecondsValue * ONE_SECOND_MS
    

    남은 밀리초


    전체 운행 시간에서 밀리초ONE_SECOND_MSwholeMinutesInMs를 쉽게 빼면 남은 밀리초를 얻을 수 있다.
    const millisecsValue = elapsed - wholeMinutesInMs - wholeSecondsInMs
    

    조립 디지털 운행 시간 읽기


    현재 나는 나의 숫자 읽기 수를 쉽게 조립하여 분과 초의 값에 0을 남기고 값이 10보다 작다는 것을 확보할 수 있다.
     const elapsedFormatted = `${wholeMinutesValue.toString().padStart(2, '0')}:` +
      `${wholeSecondsValue.toString().padStart(2, '0')}:` +
      `${millisecsValue.toString().padStart(3, '0')}`
    
    나는 이것을 보여줄 수 있다.

    동그라미 수 표시


    마지막 UI 구성 요소는 태그 링 목록입니다.나는 질서정연한 목록을 사용했지만, 순서가 반대로 되어 있어서, 가장 가까운 한 바퀴는 목록의 맨 위에 있다.
    <ol className="time lap" reversed>{ lapList }</ol>
    
    wholeSecondsInMs는 숫자 읽기와 같은 MM:SS:SS 형식의 중첩 시간 스탬프입니다.의심할 수 있는 대로 질서정연한 목록의 순서가 뒤바뀐 HTML 속성 lapList 을 주의하십시오.

    완료된 프로젝트


    내가 마침내 얻은 것은 간단하고 매끄럽고 실용적인 초시계이다:
    재미를 위해 색상을 SCSS 변수로 추상화하고 클래스로 전환하는 어두운 모드를 추가했습니다.

    나는 결과에 대해 매우 만족한다.코드는 매우 간단하지만, 문제가 있으면 아래의 댓글에 남겨 주십시오!

    좋은 웹페이지 즐겨찾기