또 flex-box를 이용해서 가운데로 옮기고, 시계 모양을 만들어줄 예정이다. 구조 짤 때에는 flex-box가 진짜 좋은 것 같다. 위치 지정하기도 굉장히 편리하고, 여러모로 마음에 든다.
HTML 코드는 간단하다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>[Javascript30] Js-Clock</title>
<link rel="stylesheet" href="style jsClock.css" />
</head>
<body>
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<script src="app jsClock.js"></script>
</body>
</html>
🤚 꼭 집고 넘어가야 하는 부분
position: relative VS absolute
시침, 분침, 초침은 absolute로 지정하고, 나머지 부분은 relative로 지정하였다. 기존의 문서의 css흐름이 달라지면 absolute를 사용하는 것은 알고 있는데, "정확하게" 이유는 잘 모르겠다.
transform: translateY(-3px)
이거는 진짜 왜 지정하는지 모르겠다. 3차원에서 y축 왼쪽으로 3px만큼 이동한다는 의미인데, 강의를 들으면서 확인해야겠다.
💙 신기하다고 느낀 부분
class가 hand 부분을 background를 이용해서 선으로 만들어주었다.
width와 height를 원하는 만큼 지정해서 선의 길이와 굵기를 지정해주었다.
clock-face 부분을 width와 height를 100%로 지정하여 모든 영역을 사용하도록 만들어주었다.
transition을 이용해서 시계가 틱톡틱톡 움직이는 느낌을 만들어준 것이 신기하다.
- transform: 단순하게 변형을 주고 싶은 경우에 이용한다.
- transition: 시간에 따라 스타일을 변형해주고 싶은 경우에 이용한다.
그래서 12시 방향으로 맞춰줄 때에는 transform: rotate(deg)를 이용했고, 빠르게 움직이게 만들어서 시계가 틱톡거리는 부분을 생성하기 위해 transition + transition-timing-function을 이용해서 cubic-bezier를 넣어주었다.
🤚 좀 아쉬운 부분...
transform-origin을 잘 이해하지 못해서, 시침 분침 초침의 길이를 줄이지 못하였다. 그래서 그냥 색깔만 다르게 지정하였다.
@import "reset.css";
html {
background: no-repeat url("ocean.jpg");
background-size: cover;
}
body {
display: flex;
flex-direction: row;
justify-content: center;
height: 100vh;
align-items: center;
}
.clock {
/* clock에서 시계 모양을 만들어준다. */
width: 400px;
height: 400px;
border: 20px solid white;
border-radius: 50%;
position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}
/* 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2); 그럴 듯하게 시계에 입체감을 줄 수 있다. */
.clock-face {
/* 시침, 분침, 초침을 이 영역에서 움직일 수 있도록 조정시켜준다. */
width: 100%;
height: 100%;
position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
transform: translateY(-3px); /* account for the height of the clock hands */
}
.hand {
width: 50%;
height: 6px;
background: rgb(252, 117, 252);
position: absolute; /* 기존의 문서 흐름대로 가지 않기 때문이다. 계속 시침, 분침, 초침은 움직여야 하기 때문이다. */
top: 50%;
}
(목표) 현재 시각을 구해서 시, 분, 초로 나누어준다. 그렇게 한 다음 1초에 한번씩 함수가 돌아가도록 제작하고, css style을 주기 위해서(시침, 분침, 초침이 돌아가야 하기 때문이다.) degree를 계산한다.
그 각도에 맞게 html에서 시침, 분침, 초침을 가르키는 객체를 불러와서 돌아가도록 제작하면 된다.
(각도 구하는 팁)
초침
1초마다 바뀐다. 1초 ~ 60초까지 있기 때문에, "(초/60)*360"을 해주면 각도가 나온다. 그런데 90deg를 돌려놨기 때문에 (12시로 맞추기 위해서)
"(초/60)*360+90"으로 해줘야한다.
분침
1분 ~ 60분까지 있기 때문에, "(분/60)*360"을 해주면 각도가 나온다. 그런데 90deg를 돌려놨기 때문에 (12시로 맞추기 위해서)
"(분/60)*360+90"으로 해줘야한다.
시침
1시 ~ 12시까지 있기 때문에, "(시/12)*360"을 해주면 각도가 나온다. 그런데 90deg를 돌려놨기 때문에 (12시로 맞추기 위해서)
"(시/12)*360+90"으로 해줘야한다.
(문제점)
처음 새로고침을 하면, 원래 css가 1초정도 보여진다. 그래서 init() 함수로 setDate() 함수를 감싸고, init() 함수를 불러오자. 그러면 바로 date를 구해주기 때문에 바로 지금 시간을 시계에 보여줄 수 있다.
const secondHand = document.querySelector(".second-hand");
// console.log(secondHand);
const minuteHand = document.querySelector(".min-hand");
const hourHand = document.querySelector(".hour-hand");
function setDate() {
const date = new Date();
// console.log(date);
const second = date.getSeconds();
// console.log(second);
const secondDegree = (second / 60) * 360 + 90; // 여기 살짝 주의하기. 아까 12시 방향으로 맞추기 위해서 90도 돌려놓았기 때문에 + 90deg을 해줘야한다.
// console.log(secondDegree);
secondHand.style.transform = `rotate(${secondDegree}deg)`;
// console.log(second);
const minute = date.getMinutes();
// console.log(minute);
const minuteDegree = (minute / 60) * 360 + 90;
minuteHand.style.transform = `rotate(${minuteDegree}deg)`;
const hour = date.getHours();
// console.log(hour);
const hourDegree = (hour / 12) * 360 + 90;
hourHand.style.transform = `rotate(${hourDegree}deg)`;
}
setInterval(setDate, 1000); // 1초에 setDate 1번씩 갱신시키기.
function init() {
setDate();
}
setDate();
시침, 분침, 초침의 길이를 조정하고 싶은데 잘 안되었다. 조정하는 순간, 원점에 놓이질 않게 되어서 할 수가 없었다. 나중에 꼭 해결하고 싶다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>[Javascript30] Js-Clock</title>
<link rel="stylesheet" href="style jsClock.css" />
</head>
<body>
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
</div>
<script src="app jsClock.js"></script>
</body>
</html>
@import "reset.css";
html {
background: no-repeat url("ocean.jpg");
background-size: cover;
}
body {
display: flex;
flex-direction: row;
justify-content: center;
height: 100vh;
align-items: center;
}
.clock {
/* clock에서 시계 모양을 만들어준다. */
width: 400px;
height: 400px;
border: 20px solid white;
border-radius: 50%;
position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
box-shadow: 0 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2);
}
/* 0 0 4px rgba(0, 0, 0, 0.1), inset 0 0 0 3px #efefef,
inset 0 0 10px black, 0 0 10px rgba(0, 0, 0, 0.2); 그럴 듯하게 시계에 입체감을 줄 수 있다. */
.clock-face {
/* 시침, 분침, 초침을 이 영역에서 움직일 수 있도록 조정시켜준다. */
width: 100%;
height: 100%;
position: relative; /* 계속 위치가 그 문서의 흐름에 따라서 가기 때문에 relative로 지정하기. */
transform: translateY(-3px); /* account for the height of the clock hands */
/* 이 부분은 왜 있는지 잘 모르겠다. */
}
.hand {
width: 50%;
height: 6px;
background: rgb(252, 117, 252);
position: absolute; /* 기존의 문서 흐름대로 가지 않기 때문이다. 계속 시침, 분침, 초침은 움직여야 하기 때문이다. */
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
/* 시간이 흐름에 따라서 효과를 주고 싶은 경우에 transition 이용하기. */
/* 시계가 틱톡틱톡 움직이는 효과를 줄 수 있다. - cubic-bezier 이용함으로서 */
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.075, 0.82, 0.165, 1);
}
.second-hand {
background-color: yellowgreen;
}
.min-hand {
background-color: rgb(64, 64, 255);
}
const secondHand = document.querySelector(".second-hand");
// console.log(secondHand);
const minuteHand = document.querySelector(".min-hand");
const hourHand = document.querySelector(".hour-hand");
function setDate() {
const date = new Date();
// console.log(date);
const second = date.getSeconds();
// console.log(second);
const secondDegree = (second / 60) * 360 + 90; // 여기 살짝 주의하기. 아까 12시 방향으로 맞추기 위해서 90도 돌려놓았기 때문에 + 90deg을 해줘야한다.
// console.log(secondDegree);
secondHand.style.transform = `rotate(${secondDegree}deg)`;
// console.log(second);
const minute = date.getMinutes();
// console.log(minute);
const minuteDegree = (minute / 60) * 360 + 90;
minuteHand.style.transform = `rotate(${minuteDegree}deg)`;
const hour = date.getHours();
// console.log(hour);
const hourDegree = (hour / 12) * 360 + 90;
hourHand.style.transform = `rotate(${hourDegree}deg)`;
}
setInterval(setDate, 1000); // 1초에 setDate 1번씩 갱신시키기.
function init() {
setDate();
}
init();
일단 작동 원리는 비슷하다. 그리고 쓰는 메소드와 함수는 동일하다.
조금은 다른 점은 있었지만, 그래도 어느 정도 비슷한 결로 제작되었다.
(Digital Clock) 하지만, 디지털 시계에서는 각도를 고려해서 바늘이 돌아갈 수 있도록 만들어야 했다. 바늘이 돌아가게 만들기 위해서 style.transform = rotate(deg) 를 이용했다. 단순한 변형은 transform이 좋다. 그리고 바늘의 위치를 가운데 맞추기 위해서 transfrom-origin 또한 이용하였다.
(Analog Clock) 아날로그 시계에서는 10보다 작은 수 앞에 0을 붙여서 깔끔하게 돌아가도록 만들어야 한다. 텍스트 내용을 바꿔야 하기 때문에 innerText를 이용해주었다.