Trong bài viết này, chúng ta sẽ tìm hiểu về hiệu ứng hoạt hình trên đồng hồ sử dụng CSS, cụ thể là CSS Watch Animation. CSS Watch Animation là một kỹ thuật cho phép tạo ra các hiệu ứng hoạt hình trên các thành phần HTML, ví dụ như đồng hồ, đồng hồ báo thức vv. bằng cách sử dụng CSS.
Lập Trình Viên mời bạn cùng tham khảo chi tiết nội dung bên dưới. Bài viết này nằm trong chuyên đề hướng dẫn CSS từ cơ bản đến nâng cao tại dự án Phát Triển Website.
Tổng quan CSS Watch Animation
CSS Watch Animation là một trong những kỹ thuật được sử dụng để tạo ra hiệu ứng hoạt hình trên các thành phần HTML. Nó cho phép bạn tạo ra các hiệu ứng hoạt hình trên các đồng hồ số hoặc đồng hồ kim. Thêm vào đó, nó cũng cho phép bạn tạo ra các hiệu ứng hoạt hình khác trên các thành phần HTML khác. Kỹ thuật này rất hữu ích cho các trang web liên quan đến đồng hồ và thời gian.
CSS Watch Animation là phương pháp tạo ra hiệu ứng hoạt hình trên các thành phần HTML như đồng hồ, đồng hồ báo thức vv. bằng cách sử dụng CSS. Kỹ thuật này cho phép bạn tạo ra các hiệu ứng hoạt hình khác nhau trên các thành phần HTML.
Hướng dẫn CSS Watch Animation
Để tạo ra hiệu ứng CSS Watch Animation, bạn có thể sử dụng một số thuộc tính CSS như animation-name, animation-duration, animation-delay, animation-iteration-count và animation-timing-function. Dưới đây là ví dụ về cách áp dụng thuộc tính animation-name để tạo ra một hiệu ứng hoạt hình trên đồng hồ số:
<div class="watch">
<div class="face">
<div class="hour-hand"></div>
<div class="minute-hand"></div>
<div class="second-hand"></div>
</div>
</div>
<style>
.watch {
width: 100px;
height: 100px;
border: 1px solid black;
background: white;
}
.face {
width: 100%;
height: 100%;
}
.hour-hand {
width: 10px;
height: 30px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
background: black;
transform-origin: center;
animation: hour-hand 12h linear infinite;
}
.minute-hand {
width: 5px;
height: 50px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
background: black;
transform-origin: center;
animation: minute-hand 60m linear infinite;
}
.second-hand {
width: 2px;
height: 100px;
border-top-left-radius: 50%;
border-bottom-left-radius: 50%;
background: black;
transform-origin: center;
animation: second-hand 60s linear infinite;
}
@keyframes hour-hand {
0% {
transform: rotate(0deg);
}
360% {
transform: rotate(360deg);
}
}
@keyframes minute-hand {
0% {
transform: rotate(0deg);
}
360% {
transform: rotate(360deg);
}
}
@keyframes second-hand {
0% {
transform: rotate(0deg);
}
360% {
transform: rotate(360deg);
}
}
</style>
Trong ví dụ này, ba hình chữ nhật được sử dụng để đại diện cho kim đồng hồ. Kim giờ có chiều dài lớn nhất, kim phút có chiều dài trung bình và kim giây có chiều dài ngắn nhất.
Các thuộc tính CSS được sử dụng để tạo hiệu ứng quay kim đồng hồ bao gồm:
transform
: Định nghĩa cách các phần tử được định vị và xoay.animation
: Định nghĩa các animation để xoay kim đồng hồ.
Kim giờ được định vị ở trung tâm của mặt đồng hồ và được xoay 360 độ trong 12 giờ. Động tác xoay được lặp lại vô hạn.
Kim phút được định vị ở trung tâm của mặt đồng hồ và được xoay 360 độ trong 60 phút. Động tác xoay được lặp lại vô hạn.
Kim giây được định vị ở trung tâm của mặt đồng hồ và được xoay 360 độ trong 60 giây. Động tác xoay được lặp lại vô hạn.
Bạn có thể điều chỉnh các thuộc tính CSS để tạo hiệu ứng quay kim đồng hồ theo sở thích của mình. Ví dụ: bạn có thể thay đổi tốc độ quay của kim đồng hồ bằng cách thay đổi giá trị của duration
. Bạn cũng có thể thay đổi màu sắc và kích thước của kim đồng hồ.
Thêm ví dụ hiệu ứng đồng hồ
Code HTML:
<div class="wrapper">
<div class="watch-strap">
<div class="strap-circle"></div>
<div class="strap"></div>
<div class="watch-strap-holder left-up"></div>
<div class="watch-strap-holder left-bottom"></div>
<div class="watch-strap-holder right-up"></div>
<div class="watch-strap-holder right-bottom"></div>
<div class="watch-lace">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<span class="top"></span>
<span class="bottom"></span>
</div>
</div>
<div class="watch-case">
<div class="reflection"></div>
<div class="reflection bottom"></div>
<div class="watch-center">
<div class="watch-points"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<div class="watch-tips">
<span class="hours"></span>
<span class="minutes"></span>
<span class="seconds"></span>
</div>
<div class="watch-date">17 SEP</div>
<div class="watch-alert">Your meeting <br>in <strong>15</strong> min</div>
<div class="watch-week">
<span class="week-arrow"></span>
<ul>
<div>S</div>
<div>M</div>
<div>T</div>
<div>W</div>
<div>T</div>
<div>F</div>
<div>S</div>
</ul>
</div>
<div class="watch-day">
<div class="sun">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div class="watch-week days">
<span class="week-arrow"></span>
<ul>
<div>3</div>
<div>6</div>
<div>9</div>
</ul>
</div>
</div>
</div>
</div>
Code CSS:
@import url('https://fonts.googleapis.com/css?family=Open+Sans:400,600,700');
body
background-color #fff
min-height 100vh
display flex
align-items center
justify-content center
font-family: 'Open Sans', sans-serif;
.wrapper
position relative
.watch
&-case
position absolute
z-index 4
top 50%
left 50%
transform translate(-50%, -50%)
height 400px
width 400px
overflow hidden
background-image linear-gradient(-45deg, #fdfdfd, #ceced6, #fdfdfd)
border-radius 50%
box-shadow:
0 0 1px 2px rgba(#b4b1c1,.7)
&-center
background-image radial-gradient(#ffffff,#eeeeef)
height 380px
width 380px
border-radius 50%
position absolute
z-index 4
left 50%
top 50%
transform translate(-50%, -50%)
box-shadow:
-1px -1px 1px 0 #fdfdfd,
0 0 0 2px #b8b7c3,
inset 0 0 0 2px #d1d1d6,
inset 0 0 0 4px rgba(#fff,.7),
inset 0 0 8px 8px rgba(#000,.1),
inset 0 0 50px 50px rgba(#000,0.05)
&-strap
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
height 480px
width 220px
background-color #101022
border-radius 6px
z-index 2
.strap-circle
position absolute
height 409px
width 409px
background-color transparent
top 50%
left 50%
transform translate(-50%, -50%)
border-radius 50%
box-shadow:
inset -1px 0 8px 3px #151427,
0 0 2px 1px rgba(#fff,.8)
&:after
content ""
display block
height 100%
width 72px
left -2px
position absolute
background-color #fff
&:before
content ""
display block
height 100%
width 72px
background-color #fff
position absolute
right -2px
.strap
position absolute
top 50%
left 50%
transform translate(-50%, -50%)
height 480px
width 220px
background-color #101022
border-radius 6px
z-index 2
box-shadow:
-1px 0 1px 0 #000,
inset 0 20px 40px -20px rgba(#172365,1),
inset 0 -20px 40px -20px rgba(#172365,.7)
&-holder
position absolute
background-color #e7e7ea
height 150px
width 20px
left -20px
border-radius 3px
top -2px
z-index -1
box-shadow:
inset 0 0 4px 1px rgba(#000,0.2)
&.left-bottom
transform scaleY(-1)
top 332px
left -20px
&.right-up
transform scaleX(-1)
left 220px
box-shadow:
inset 0 0 4px 1px rgba(#000,0.2)
&:after
border-radius 14px 70px 0 0
box-shadow:
inset 0px 3px 1px -2px rgba(#fff,.6),
inset -10px -15px 1px 2px rgba(#dcdce4,1),
inset -2px 10px 4px 2px rgba(#181820,1)
&.right-bottom
transform scaleY(-1) scaleX(-1)
top 332px
left 220px
&:after
border-radius 14px 70px 0 0
box-shadow:
inset 0px 3px 1px -2px rgba(#fff,.6),
inset -10px -15px 1px 2px rgba(#dcdce4,1),
inset -2px 10px 4px 2px rgba(#181820,1)
&:before
content ""
display block
position absolute
background-color #e7e7ea
height 150px
width 10px
border-radius 3px 0
transform rotate(4deg)
left -5px
box-shadow:
inset 5px 5px 4px -5px rgba(#000,0.2)
&:after
content ""
display block
position absolute
background-color transparent
background-image linear-gradient(to bottom, transparent, #fff)
height 150px
width 30px
border-radius 12px
transform rotate(4deg)
top 10px
left -4px
box-shadow:
inset -3px 8px 2px 2px rgba(#181820,1)
.reflection
content ""
display block
height 16px
width 30px
position absolute
top 50px
left 50px
background-color #080817
filter blur(1px)
transform rotate(-56deg) skewX(30deg) scale(.6)
&.bottom
top 337px
left 312px
&:after
height 39px
width 43px
left -60px
top -14px
transform rotate(-44deg)
box-shadow:
34px 17px 0 8px #080817
&:after
content ""
display block
background-color transparent
height 40px
width 30px
border-radius 50%
background-color transparent
position absolute
left -48px
top -11px
transform rotate(-69deg)
box-shadow:
34px 17px 0 20px #080817
&:before
content ""
display block
background-color transparent
height 40px
width 30px
border-radius 50%
background-color transparent
position absolute
right 25px
top 32px
transform rotate(-69deg)
box-shadow:
34px 17px 0 10px #080817,
14px 32px 0 20px #080817
.watch-points
position absolute
z-index 5
top calc(50% - 6px)
left calc(50% - 1px)
transform translate(-50%, -50%)
&:after
content ""
display block
height 325px
width 325px
position absolute
border 2px solid #dededf
top calc(50% + 6px)
left calc(50% + 1px)
transform translate(-50%, -50%)
border-radius 50%
i
display block
height 12px
width 2px
background-image linear-gradient(to bottom, #c6c6cb, #e0e0e1)
position absolute
i
for num in (1..60)
&:nth-child({num})
transform rotate((num*360/60-6)deg) translate(0, -172px)
.watch-week
position absolute
top calc(50% - 6px)
left calc(50% - 6px)
transform translate(-120px, 40px) rotate(-70deg)
z-index 10
&.days
transform translate(50px, 40px) rotate(-70deg)
&:after
transform rotate(256deg)
ul
transform rotate(169deg) translate(-58px, -17px)
div
color #1F1F21
&:nth-child(1)
transform rotate(0) translate(0, -37px) scaleX(-1)
&:nth-child(2)
transform rotate(80deg) translate(0, -37px) scaleX(-1) scaleY(-1)
&:nth-child(3)
transform rotate(160deg) translate(0, -37px)
.week-arrow
transform rotate(115deg) translate(35px,-8px)
&:after
content ""
display block
height 100px
width 100px
border-radius 50%
background-color transparent
transform rotate(-64deg)
box-shadow 1px 2px 0 0px #d6d6d3
position absolute
left -2px
top -28px
.week-arrow
position absolute
top 50%
left 50%
transform translate(19px, 21px) rotate(22deg)
width 45px
height 2px
background-color #0f1743
z-index 5
&:after, &:before
content ""
position absolute
display block
height 14px
width 14px
background-color #ff5456
border-radius 50%
left -6px
top -6px
z-index -1
&:after
background-color #0f1743
height 10px
width 10px
top -4px
left -4px
z-index -1
div
font-weight bold
font-size 11px
position absolute
z-index 10
height 12px
width 12px
display block
color #d6d6d3
&:nth-child(1)
transform rotate(0) translate(0, -45px)
&:nth-child(2)
transform rotate(25deg) translate(0, -45px)
&:nth-child(3)
transform rotate(50deg) translate(0, -45px)
&:nth-child(4)
transform rotate(75deg) translate(0, -45px)
&:nth-child(5)
transform rotate(100deg) translate(0, -45px)
&:nth-child(6)
transform rotate(125deg) translate(0 ,-45px)
color #ff5456
&:nth-child(7)
transform rotate(150deg) translate(0 ,-45px)
.watch-date
position absolute
top calc(50% - 100px)
left 50%
font-size 14px
font-weight 600
letter-spacing 1px
transform translate(-50%, -50%)
.watch-alert
position absolute
top calc(50% + 100px)
text-transform uppercase
text-align center
left 50%
font-size 14px
color #BFBCD8
font-weight 600
transform translate(-50%, -50%)
strong
color #FF0000
font-weight 600
.watch-tips
height 300px
width 300px
position absolute
top 50%
left 50%
transform translate(-50%, -50%) rotate(-90deg)
z-index 11
.hours
width 190px
height 6px
position absolute
top calc(50% - 3px)
left calc(50% - 30px)
transform rotate(153deg)
background-color #fff
transform-origin 30px center
box-shadow 0 4px 12px 2px rgba(#000,0.15)
border-radius 0 20px 20px 0
z-index 12
&:after
content ""
display block
position absolute
left 23px
top -5px
height 14px
width 14px
background-color #fff
border-radius 50%
.seconds
width 197px
height 2px
position absolute
top 50%
left calc(50% - 30px)
transform rotate(0deg)
animation 10s seconds linear infinite
background-color #FE0806
transform-origin 30px center
box-shadow 0 0 16px 2px rgba(#FE0806,0.2)
border-radius 0 20px 20px 0
z-index 15
&:after
content ""
display block
position absolute
left 25px
top -4px
height 10px
width 10px
background-color #FE0806
border-radius 50%
z-index 15
.minutes
width 170px
height 6px
position absolute
top calc(50% - 3px)
left calc(50% - 30px)
transform rotate(15deg)
background-color #000004
transform-origin 30px center
border-radius 0 20px 20px 0
z-index 11
@keyframes seconds
0%
transform rotate(0deg)
100%
transform rotate(360deg)
.watch-lace
width 0
height 20px
border-bottom 10px solid transparent
border-top 10px solid transparent
border-right 8px solid #32322A
position absolute
right -98px
top calc(50% - 20px)
border-radius 6px
z-index 30
transform scaleX(.9) scaleY(1.1)
&:after
content ""
display block
height 40px
width 10px
right -16px
top -10px
background-color #DEDEDE0
border-radius 3px
position absolute
&:before
content ""
display block
height 40px
width 4px
background-color #C3C4CB
background-image linear-gradient(to left, transparent, rgba(#000,0.1))
z-index 20
position absolute
right -17px
border-radius 4px
top -10px
span
display block
position absolute
background-image linear-gradient(to left, #EAE9E9, transparent)
height 4px
width 20px
top -4px
left -10px
transform rotate(-45deg)
box-shadow
0 2px 2px 0 rgba(#fff,0.2)
&.bottom
top 18px
transform rotate(45deg)
background-image linear-gradient(to left, #EAE9E9, transparent)
opacity .7
div
height 2px
width 7px
background-color #C4C4C4
border 1px solid #999891
position relative
right -7px
z-index 20
top 7px
&:nth-child(2)
top -4px
&:nth-child(3)
top 6px
&:nth-child(4)
top -17px
filter brightness(110%)
&:nth-child(5)
top 4px
filter brightness(110%)
&:nth-child(6)
top -28px
transform rotate(-4deg)
filter brightness(115%)
&:before
transform rotate(-8deg)
&:nth-child(7)
top -1px
transform rotate(4deg)
filter brightness(115%)
&:after
transform rotate(8deg)
&:after, &:before
content ""
position relative
background-color #B8B8BB
height 3px
width 10px
display block
top 0px
left -3px
border-radius 3px
&:before
top -3px
.watch-day
height 90px
width 90px
display block
position absolute
top 50%
left 50%
transform translate(42px, -23px)
background-color #1341D1
animation 8s day-bg infinite
border-radius 50%
overflow hidden
box-shadow:
inset 0 -1px 1px 1px #F6F6F6
background-image:
radial-gradient(#F6F6F6 18px, transparent 19px),
radial-gradient(#F6F6F6 14px, transparent 15px),
radial-gradient(#F6F6F6 18px, transparent 19px),
radial-gradient(#F6F6F6 60px, transparent 61px)
background-repeat no-repeat
background-position:
-28px 6px,
0 6px,
28px 6px,
0 42px
.sun
height 10px
width 10px
background-color transparent
position absolute
border 3px solid #fff
border-radius 50%
left calc(50% - 8px)
top 12px
animation 8s sun infinite
&:after
content ""
display block
position absolute
height 20px
width 20px
background-color #212045
border-radius 50%
top calc(50% - 10px)
left calc(50% - 10px)
animation 8s moon infinite
div
position absolute
height 7px
width 1px
background-color #fff
top calc(50% - 7px/2)
left calc(50% - 1px)
border-radius 10px
animation 8s sun-arms infinite
&:after, &:before
content ""
display block
height 7px
width 2px
background-color #fff
position absolute
left 1px
border-radius 4px
transform rotate(-10deg)
&:before
transform rotate(10deg)
left -1px
&:nth-child(1)
transform rotate(0) translate(0, -9px)
&:nth-child(2)
transform rotate(45deg) translate(0, -9px)
&:nth-child(3)
transform rotate(90deg) translate(0, -9px)
&:nth-child(4)
transform rotate(135deg) translate(0, -9px)
&:nth-child(5)
transform rotate(180deg) translate(0, -9px)
&:nth-child(6)
transform rotate(225deg) translate(0, -9px)
&:nth-child(7)
transform rotate(270deg) translate(0, -9px)
&:nth-child(8)
transform rotate(315deg) translate(0, -9px)
&:nth-child(9)
transform rotate(360deg) translate(0, -9px)
@keyframes sun
0%, 33%
transform rotate(0)
height 12px
width 12px
33%
background-color #fff
transform rotate(180deg)
height 12px
width 12px
66%
transform rotate(180deg)
background-color #fff
height 12px
width 12px
100%
background-color transparent
transform rotate(360deg)
height 10px
width 10px
@keyframes sun-arms
0%
opacity 1
20%, 55%
opacity 0
100%
opacity 1
@keyframes moon
0%
transform translate(-14px, 14px)
opacity 0
25%
transform translate(-14px, 14px)
opacity 1
45%
transform translate(0px, 0px)
opacity 1
50%
transform translate(14px, -14px)
opacity 0
50%
opacity 0
100%
transform translate(0, 0)
opacity 0
@keyframes day-bg
0%
background-color #2b7edc
8%,50%
background-color #212045
60%
background-color #1341D1
100%
background-color #2b7edc
Kết Quả:
Ưu và Nhược điểm CSS Watch Animation
Ưu điểm của CSS Watch Animation là nó giúp tạo ra các hiệu ứng hoạt hình mượt mà và hấp dẫn trên các thành phần HTML như đồng hồ, đồng hồ báo thức vv. Nó cũng giúp tăng tính tương tác của trang web và thu hút người dùng. Tuy nhiên, một nhược điểm của kỹ thuật này là nó có thể tốn nhiều thời gian để phát triển và bảo trì.
Lời khuyên CSS Watch Animation
Để tạo ra hiệu ứng hoạt hình CSS Watch Animation, bạn cần phải biết cách sử dụng các thuộc tính CSS như animation-name, animation-duration, animation-delay, animation-iteration-count và animation-timing-function. Ngoài ra, hãy đảm bảo rằng bạn chỉ sử dụng các hiệu ứng hoạt hình khi cần thiết và không lạm dụng chúng, vì điều này có thể ảnh hưởng đến tốc độ tải trang web.
CSS Watch Animation là gì?
CSS Watch Animation là một kỹ thuật cho phép tạo ra các hiệu ứng hoạt hình trên các thành phần HTML như đồng hồ, đồng hồ báo thức vv. bằng cách sử dụng CSS.
CSS Watch Animation có gì đặc biệt?
CSS Watch Animation cho phép tạo ra các hiệu ứng hoạt hình mượt mà và hấp dẫn trên các thành phần HTML như đồng hồ.
Các thuộc tính nào được sử dụng để tạo ra hiệu ứng hoạt hình trên CSS Watch Animation?
Một số thuộc tính CSS được sử dụng để tạo ra hiệu ứng hoạt hình trên CSS Watch Animation bao gồm animation-name, animation-duration, animation-delay, animation-iteration-count và animation-timing-function.
Nhược điểm của CSS Watch Animation là gì?
Một nhược điểm của CSS Watch Animation là nó có thể tốn nhiều thời gian để phát triển và bảo trì.
Lời khuyên nào cho việc sử dụng CSS Watch Animation?
Để sử dụng CSS Watch Animation hiệu quả, bạn cần phải biết cách sử dụng các thuộc tính CSS liên quan.