JS30 Day02
這次的課程提到了 CSS 與 JS 的 transform 屬性,對動畫有多一點的了解~


JS and CSS Clock

完成目標

  • 功能
    • 顯示目前的時間
      • 更新時針、分針、秒針
  • 畫面
    • 讀得到目前的時間
    • 秒針要有「真實的滴答」動作



index-START.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JS + CSS Clock</title>
</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>

<style>
html {
background: #018ded url(http://unsplash.it/1500/1000?image=881&blur=5);
background-size: cover;
font-family: "helvetica neue";
text-align: center;
font-size: 10px;
}

body {
margin: 0;
font-size: 2rem;
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
}

.clock {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
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);
}

.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(
-3px
); /* account for the height of the clock hands */
}

.hand {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
}
</style>

<script></script>
</body>
</html>

index-FINISHED.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>JS + CSS Clock</title>
</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>

<style>
html {
background: #018ded url(http://unsplash.it/1500/1000?image=881&blur=5);
background-size: cover;
font-family: "helvetica neue";
text-align: center;
font-size: 10px;
}

body {
margin: 0;
font-size: 2rem;
display: flex;
flex: 1;
min-height: 100vh;
align-items: center;
}

.clock {
width: 30rem;
height: 30rem;
border: 20px solid white;
border-radius: 50%;
margin: 50px auto;
position: relative;
padding: 2rem;
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);
}

.clock-face {
position: relative;
width: 100%;
height: 100%;
transform: translateY(
-3px
); /* account for the height of the clock hands */
}

.hand {
width: 50%;
height: 6px;
background: black;
position: absolute;
top: 50%;
transform-origin: 100%;
transform: rotate(90deg);
transition: all 0.05s;
transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
</style>

<script>
const secondHand = document.querySelector(".second-hand");
const minsHand = document.querySelector(".min-hand");
const hourHand = document.querySelector(".hour-hand");

function setDate() {
const now = new Date();

const seconds = now.getSeconds();
const secondsDegrees = (seconds / 60) * 360 + 90;
secondHand.style.transform = `rotate(${secondsDegrees}deg)`;

const mins = now.getMinutes();
const minsDegrees = (mins / 60) * 360 + (seconds / 60) * 6 + 90;
minsHand.style.transform = `rotate(${minsDegrees}deg)`;

const hour = now.getHours();
const hourDegrees = (hour / 12) * 360 + (mins / 60) * 30 + 90;
hourHand.style.transform = `rotate(${hourDegrees}deg)`;
}

setInterval(setDate, 1000);

setDate();
</script>
</body>
</html>



學習筆記


★ CSS transform-origin

CSS 內的 transform-origin 屬性可以設定元素變化的原點。在這個範例中,設定為 100%(right)可以使其從時鐘面的中心點開始旋轉。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/* One-value syntax */
transform-origin: 2px;
transform-origin: bottom;

/* x-offset | y-offset */
transform-origin: 3cm 2px;

/* x-offset-keyword | y-offset */
transform-origin: left 2px;

/* x-offset-keyword | y-offset-keyword */
transform-origin: right top;

/* y-offset-keyword | x-offset-keyword */
transform-origin: top right;

/* x-offset | y-offset | z-offset */
transform-origin: 2px 30% 10px;

/* x-offset-keyword | y-offset | z-offset */
transform-origin: left 5px -3px;

/* x-offset-keyword | y-offset-keyword | z-offset */
transform-origin: right bottom 2cm;

/* y-offset-keyword | x-offset-keyword | z-offset */
transform-origin: bottom right 2cm;

/* Global values */
transform-origin: inherit;
transform-origin: initial;
transform-origin: unset;

★ CSS transform

CSS 內的 transition 屬性可以進行 2D 和 3D 的變化。

transition 共包含四種子屬性: transition-property , transition-duration , transition-timing-function , transition-delay

  • transition-property:指定做變換的 CSS 屬性。
  • transition-duration:變換過程的總時間。
  • transition-timing-function:定義變換時的速度曲線。
  • transition-delay:延遲多久後開始變換。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/* Apply to 1 property */
/* property name | duration */
transition: margin-right 4s;

/* property name | duration | delay */
transition: margin-right 4s 1s;

/* property name | duration | timing function */
transition: margin-right 4s ease-in-out;

/* property name | duration | timing function | delay */
transition: margin-right 4s ease-in-out 1s;

/* Apply to 2 properties */
transition: margin-right 4s, color 1s;

/* Apply to all changed properties */
transition: all 0.5s ease-out;

/* Global values */
transition: inherit;
transition: initial;
transition: unset;

★ CSS transition-timing-function

transition 中其中一個子屬性 transition-timing-function 定義過渡效果的速度曲線。預設為 ease

描述
linear 規定以相同速度開始至結束的過渡效果(等於 cubic-bezier(0,0,1,1))。
ease 規定慢速開始,然後變快,然後慢速結束的過渡效果(cubic-bezier(0.25,0.1,0.25,1))。
ease-in 規定以慢速開始的過渡效果(等於 cubic-bezier(0.42,0,1,1))。
ease-out 規定以慢速結束的過渡效果(等於 cubic-bezier(0,0,0.58,1))。
ease-in-out 規定以慢速開始和結束的過渡效果(等於 cubic-bezier(0.42,0,0.58,1))。
cubic-bezier( n , n , n , n ) 在 cubic-bezier 函數中定義自己的值。可能的值是 0 至 1 之間的數值。

★ Date()

JS 取得時間的函式,需搭配 new 來使用,如 new Date()

*注意:JavaScript Date 物件只能由以 Date 作為建構子來產生,如果把 Date 作為一般的函式來呼叫(省略 new),將會得到一個字串而非 Date 物件。它並沒有物件實體語法(例如:以中刮號 [ ] 表示陣列的宣告方式)。

範例:

1
2
3
4
new Date();
new Date(value);
new Date(dateString);
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);
  • Date.prototype 方法
    • date.getSeconds():取得當前秒
    • date.getMinutes():取得當前分鐘
    • date.getHours():取得當前小時

★ style.transform

transform 屬性使物件進行 2D 或 3D 的轉換。例如:旋轉、縮放、移動或傾斜。

範例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<button onclick="myFunction()">Try it</button>

<div id="myDIV">
<h1>myDIV</h1>
</div>

<script>
function myFunction() {
// Code for Safari
document.getElementById("myDIV").style.WebkitTransform = "rotate(20deg)";
// Code for IE9
document.getElementById("myDIV").style.msTransform = "rotate(20deg)";
// Standard syntax
document.getElementById("myDIV").style.transform = "rotate(20deg)";
}
// 物件旋轉20度
</script>