2020. 7. 23. 18:30ㆍ웹돌이 단편선
웹으로 낙서하기 시리즈를 여는 글로써, 자바스크립트를 사용해 디지털 시계를 만들어보겠습니다.
필요한 기능
- 현재 시간을 HH:mm:ss 포맷으로 보여준다.
- 디지털 시계다.
- 1초마다 초가 흐른다.
필요한 기능은 이정도만 있으면 될것 같으니 바로 작업을 시작하면 될것같다.
첫 시작
먼저 현재시간을 보여준다.
import React from "react";
function DigitalClock() {
return <div>{new Date().toString()}</div>;
}
export default DigitalClock;
이제 시계에 보여주고 싶은 HH:mm:ss에 대한 값만 추려서 화면에 뿌려주면 된다.
HH
, mm
, ss
를 가져오는 메소드는 각각 아래와 같다.
mm
- Date.prototype.getMinutes
ss
- Date.prototype.getSeconds
메소드들을 사용하여 코드를 수정해보았다. 현재시간 13시 03분 41초였다.
import React from "react";
function DigitalClock() {
const date = new Date();
const HH = date.getHours();
const mm = date.getMinutes();
const ss = date.getSeconds();
return <div>{`${HH}:${mm}:${ss}`}</div>;
}
export default DigitalClock;
화면에 보여지는 결과는 위와 같다. 시간, 분, 초가 각각 10미만의 정수일때 00 ~ 09의 포맷으로 보이도록 처리가 필요하다.
1 ~ 10의 자릿수까지의 입력에 대하여, 한자릿수만 받으면 앞에 0을 붙이는 함수를 선언했다.
function getZeroPadString(number) {
return number.toString().replace(/([0-9])?([0-9])$/g, function (_, $1, $2) {
return `${$1 || 0}${$2}`;
});
}
함수를 사용해서 이제 원하는 포맷으로 표현이 된다! 이제 디지털 시계처럼 숫자를 보여주는 작업을 해보겠다.
Digit 컴포넌트 만들기
우선 DigitalClock 컴포넌트를 이정도까진 만들고, Digit 컴포넌트를 추가한다.
import React from "react";
import Digit from "../../atoms/Digit";
function getZeroPadString(number) {
return number.toString().replace(/([0-9])?([0-9])$/g, function (_, $1, $2) {
return `${$1 || 0}${$2}`;
});
}
function mapDigit(digit, i) {
return <Digit key={i} value={digit} />;
}
function DigitalClock() {
const date = new Date("2020-07-20 13:03:41");
const HH = getZeroPadString(date.getHours());
const mm = getZeroPadString(date.getMinutes());
const ss = getZeroPadString(date.getSeconds());
return (
<div>
{Array.from(HH).map(mapDigit)}:{Array.from(mm).map(mapDigit)}:
{Array.from(ss).map(mapDigit)}
</div>
);
}
export default DigitalClock;
Digit
Digit.js
import React from "react";
import PropTypes from "prop-types";
import c from "./Digit.module.scss";
function Digit({ value }) {
return <div className={c["wrapper"]}>{value}</div>;
}
Digit.defaultProps = { value: 0 };
Digit.propTypes = { value: PropTypes.number };
export default Digit;
Digit.module.scss
.wrapper {
display: inline-block;
}
Digit 컴포넌트 내용을 채워서 원하는 디지털 시계의 모양을 만들어보자!
일단 비트맵 느낌의 Digit 컴포넌트를 만들어봤다. 코드는 다음과 같다.
Digit.js
import React from "react";
import PropTypes from "prop-types";
import c from "./Digit.module.scss";
function Digit({ value }) {
return (
<div className={c["wrapper"]}>
{new Array(3)
.fill("horizontal")
.concat(new Array(4).fill("vertical"))
.map((orientation, i) => (
<div
className={
c["dash"] + " " + c[orientation] + " " + c[`dash-${i + 1}`]
}
/>
))}
</div>
);
}
Digit.defaultProps = { value: 0 };
Digit.propTypes = { value: PropTypes.number };
export default Digit;
Digit.module.scss
.wrapper {
margin: 0 0.1em;
display: inline-block;
position: relative;
width: 0.5em;
height: 1em;
vertical-align: text-top;
.dash {
width: 4px;
height: 4px;
background-color: black;
position: absolute;
&.horizontal {
width: 0.5em;
left: 50%;
transform: translateX(-50%) translateY(-2px);
}
&.vertical {
height: 0.5em;
transform: translateX(-50%) translateY(0);
}
&.dash-1 {
top: 0;
}
&.dash-2 {
top: 50%;
}
&.dash-3 {
top: 100%;
}
&.dash-4,
&.dash-5 {
top: 0%;
}
&.dash-6,
&.dash-7 {
top: 50%;
}
&.dash-4,
&.dash-6 {
left: 0;
}
&.dash-5,
&.dash-7 {
left: 100%;
}
}
}
8비트 감성의 시계가 얼추 모양을 드러내는것 같으니, 이제 시간 분별이 가능하도록 생명을 불어넣겠다. 각각의 dash 요소가 on, off 상태를 갖도록 할것이다.
Digit.module.scss
.wrapper {
margin: 0 0.1em;
display: inline-block;
position: relative;
width: 0.5em;
height: 1em;
vertical-align: text-top;
.dash {
width: 4px;
height: 4px;
background-color: #cccccc;
position: absolute;
transition: background-color 0.3s ease;
&.active {
background-color: #000000;
}
&.horizontal {
width: 0.5em;
left: 50%;
transform: translateX(-50%) translateY(-2px);
}
&.vertical {
height: 0.5em;
transform: translateX(-50%) translateY(0);
}
&.dash-1 {
top: 0;
}
&.dash-2 {
top: 50%;
}
&.dash-3 {
top: 100%;
}
&.dash-4,
&.dash-5 {
top: 0%;
}
&.dash-6,
&.dash-7 {
top: 50%;
}
&.dash-4,
&.dash-6 {
left: 0;
}
&.dash-5,
&.dash-7 {
left: 100%;
}
}
}
.dash 요소에 대해서 .active라는 클래스의 스타일을 추가하고, Digit.js 파일은 각 value에 대해서 각 선이 가져야할 active 상태에 대한 배열을 정의한다.
import React from "react";
import PropTypes from "prop-types";
import c from "./Digit.module.scss";
const ENTIRE_STATE_MATRIX = [
[1, 0, 1, 1, 1, 1, 1],
[0, 0, 0, 0, 1, 0, 1],
[1, 1, 1, 0, 1, 1, 0],
[1, 1, 1, 0, 1, 0, 1],
[0, 1, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 0, 0, 1],
[1, 1, 1, 1, 0, 1, 1],
[1, 0, 0, 1, 1, 0, 1],
[1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0, 1],
];
function Digit({ value }) {
const stateMatrix = ENTIRE_STATE_MATRIX[value];
return (
<div className={c["wrapper"]}>
{new Array(3)
.fill("horizontal")
.concat(new Array(4).fill("vertical"))
.map((orientation, i) => (
<div
className={
c["dash"] +
" " +
c[orientation] +
" " +
c[`dash-${i + 1}`] +
(stateMatrix[i] ? " " + c["active"] : "")
}
/>
))}
</div>
);
}
Digit.defaultProps = { value: 0 };
Digit.propTypes = { value: PropTypes.number };
export default Digit;
모든 숫자가 잘 나오는지 App.js에 나열하여 확인해보았다.
import React from "react";
import Digit from "./components/atoms/Digit";
function App() {
return new Array(10).fill(null).map((_, i) => <Digit value={i} />);
}
export default App;
만족스럽다.
만든 Digit 컴포넌트를 사용하여 DigitalClock를 보여주고 남은 부분은 1초마다 현재 시간을 가져와서 화면에 보여주면 될것같다.
추가적인 부분은 추가적인 글을 게시해서 풀어가야겠다.
'웹돌이 단편선' 카테고리의 다른 글
[웹으로 낙서하기#3]자바스크립트로 스탑워치를 만들어보자! (6) | 2020.07.30 |
---|---|
[웹으로 낙서하기#2]디지털 시계의 시간을 흐르게 해보자! (3) | 2020.07.27 |
VSCode로 리액트 개발할 때 쓰기 편한 스니펫 모음 (1) | 2020.07.18 |