<canvas> 是HTML中的一個元素,它可被用來通過 JavaScript(Canvas API 或 WebGL API)繪制圖形及圖形動畫。
Canvas API 提供了一個通過 JavaScript 和 HTML 的 <canvas> 元素來繪制圖形的方式。它可以用于動畫、游戲畫面、數據可視化、圖片編輯以及實時視頻處理等方面。
<canvas>標簽本身沒有繪圖能力,它僅僅是圖形的容器。在HTML,一般通過Javascript語言來完成實際的操作。
本文通過Javascript操作Canvas制作一個簡單的顯示當前時間的動畫時鐘,了解和學習簡單的canvas用法,僅以拋磚引玉。
首先創建一個HTML文件,為了方便管理,使用一個div標簽包裹兩個canvas標簽,并加上一些簡單的css樣式。
<!doctype html>
<html lang="zh-cn">
<head><title>Canvas繪制動畫時鐘</title>
<style>
html,body{margin:0;padding:0}
#clockWrap {
position: relative;
}
canvas {
position: absolute;
}
#clock-ui {
z-index: 2;
}
#clock-plate {
z-index: 1;
}
</style>
</head>
<body>
<div id="clockWrap">
<canvas id="clock-plate"></canvas>
<canvas id="clock-ui"></canvas>
</div>
<script></script>
</body></html>
本示例中使用了兩個canvas標簽(為什么使用兩個,一個不是更簡單嗎?),一個用于繪制鐘面,一個根據當前時間實時顯示和更新時針、分針和秒針的動態指向。好了,話不多說,開干。
一個簡單的時鐘,可以分為鐘面上的刻度和指針。其中刻度和12個數字是固定的,我們可以將它們繪制在當作背景的canvas上(示例中id為clock-plate的canvas)。
(1)要使用canvas,首先必須通過容器獲取渲染上下文:
var $=function(id){return document.querySelector(id);}//這個函數只是為了方便獲取dom元素
const canvasbg=$("#clock-plate"),
canvas=$("#clock-ui"),
ctx = canvasbg.getContext("2d"),//背景容器上下文
ctxUI = canvas.getContext("2d");//指針容器上下文,后面代碼要用
//定義畫布寬度和高度,時鐘圓直徑,并設置畫布大小
const oW=1000,oH=800,cW=400,r=cW/2,oX=oW/2,oY=oH/2;
canvas.width=oW;
canvas.height=oH;
canvasbg.width=oW;
canvasbg.height=oH;
(2)畫鐘的邊框,為了好看,這里畫兩個圈:
//畫出時鐘外圓框
ctx.lineWidth = 12;
ctx.beginPath();
ctx.arc(oX, oY, r+14, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.lineWidth = 8;
//畫出時鐘內圓框(刻度圈)
ctx.beginPath();
ctx.arc(oX, oY, r, 0, 2 * Math.PI);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
邊框效果圖
(3)繪制刻度線和數字,可以利用三角函數計算出每個刻度的坐標:
利用三角函數計算刻度線的坐標位置
鐘面上有12個大格,從正上方12開始,它們的度數分別是270,300,330,0,30,60,90,120,150,180,210,240。然后利用JS的Math.sin和Math.cos分別計算出各大格的坐標。注意:js中Math.sin()和Math.cos()的參數不是角度數是弧度。可以使用Math.PI/180*角度來轉化,比如將30度轉換成弧度=Math.PI/180*30
//繪制鐘表中心點
ctx.beginPath();
ctx.arc(oX, oY, 8, 0, 2 * Math.PI);//圓心
ctx.fill();
ctx.closePath();
//設置刻度線粗細度
ctx.lineWidth = 3;
//設置鐘面12個數字的字體、大小和對齊方式
ctx.font = "30px serif";
ctx.textAlign="center";
ctx.textBaseline="middle";
var kdx,kdy;
//繪制12個大刻度和12個數字
//為方便計算,先定義了0-11這12個刻度對應的度數,也可以直接定義對應的弧度。
const hd=Math.PI/180,degr=[270,300,330,0,30,60,90,120,150,180,210,240];
for(var i=0;i<12;i++){
kdx=oX+Math.cos(hd*degr[i])*(r-3);
kdy=oY+Math.sin(hd*degr[i])*(r-3);
ctx.beginPath();
ctx.arc(kdx, kdy, 6, 0, 2 * Math.PI);//畫圓形大刻度
ctx.fill();
//繪制刻度對應的數字
ctx.strokeText(i==0? 12 : i,oX+Math.cos(hd*degr[i])*(r-24),oY+Math.sin(hd*degr[i])*(r-24));
ctx.closePath();
}
//繪制小刻度
ctx.lineWidth = 2;
for(var i=0;i<60;i++){
if(i % 5 == 0) continue;//跳過與刻度重疊的刻度
x0=Math.cos(hd*i*6);
y0=Math.sin(hd*i*6);
ctx.beginPath();
ctx.moveTo(oX+x0*(r-10), oY+y0*(r-10));
ctx.lineTo(oX+x0*r, oY+y0*r); //畫短刻度線
ctx.stroke();
ctx.closePath();
}
效果如圖:
鐘面效果圖
(4)根據當前時間繪制指針
習慣上,時針粗短,分針略粗而長,秒針細長。為加大區別,示例中秒針細長并且繪制成紅色。
function drawHp(i){//繪制時針
const x0=Math.cos(hd*i*30),y0=Math.sin(hd*i*30);
drawPointer(oX,oY,oX+x0*(r-90),oY+y0*(r-90),10,"#000000");
}
function drawMp(i){//繪制分針
const x0=Math.cos(hd*i*6),y0=Math.sin(hd*i*6);
drawPointer(oX,oY,oX+x0*(r-60),oY+y0*(r-60),5,"#000000");
}
function drawSp(i){//繪制秒針
const x0=Math.cos(hd*i*6),y0=Math.sin(hd*i*6);
drawPointer(oX,oY,oX+x0*(r-20),oY+y0*(r-20),2,"#FF0000");
}
//抽取出繪制三種指針時共同的部分,注意指針繪制在渲染上下文ctxUI中
function drawPointer(ox,oy,tx,ty,width,color){
ctxUI.strokeStyle = color;
ctxUI.lineCap = "round";
ctxUI.lineWidth = width;
ctxUI.beginPath();
ctxUI.moveTo(ox, oy);
ctxUI.lineTo(tx,ty);
ctxUI.stroke();
ctxUI.closePath();
}
現在已經有了繪制三種指針的方法,參數是當前時間的時、分和秒,將根據它們的值確定指針的坐標。不過,因為使用的是默認的convas坐標體系,0值實際指向3的位置,需要小小的修正一下。
window.requestAnimationFrame(function fn(){
var d = new Date();
ctxUI.clearRect(0,0,oW,oH);
//度數從0開始,而0在3刻度(15分/秒位置),修正為全值減15,如果小于0則修正回來
var hour=d.getHours(),minute=d.getMinutes()-15,second=d.getSeconds()-15;
hour=hour>11? hour-15 : hour-3;
drawHp(hour>=0? hour : 12+hour);
drawMp(minute>=0? minute : 60+minute);
drawSp(second>=0? second : 60+second);
window.requestAnimationFrame(fn);
});
接下來,調用window.requestAnimationFrame,在其中繪制并更新指標的位置。看看效果如何:
指針繪制情況與實際時間相符
貌似效果有了,截圖時電腦上的時間是10時17分,指針繪制上,時針指向10時,分針指向17。嗯,感覺有點別扭?對了,時針和分針怎么是端端正正地指向它們的整時整分刻度上呢?實際鐘表上時針和分針是展示動態進度的,此時時針應該越過10時的位置才對。沒關系,我們在繪制時針和分針時別點東西,讓它的角度值加上分針和秒針的值試試。
//修改后的繪制三種指針的方法
function drawHp(i,f,m){//繪制時針,參數:時,分,秒
const x0=Math.cos(hd*(i+(f/60)+(m/600))*30),y0=Math.sin(hd*(i+(f/60)+(m/600))*30);
drawPointer(oX,oY,oX+x0*(r-90),oY+y0*(r-90),10,"#000000");
}
function drawMp(i,f){//繪制分針,參數,分,秒
const x0=Math.cos(hd*(i+(f/60))*6),y0=Math.sin(hd*(i+(f/60))*6);
drawPointer(oX,oY,oX+x0*(r-60),oY+y0*(r-60),5,"#000000");
}
function drawSp(i){//繪制秒針
const x0=Math.cos(hd*i*6),y0=Math.sin(hd*i*6);
drawPointer(oX,oY,oX+x0*(r-20),oY+y0*(r-20),2,"#FF0000");
}
再來看看效果,嗯,立竿見影呀:
指針指向更合理了
到此為止,canvas繪制一個簡易時鐘就完成了。下面繼續優化一下。剛才使用requestAnimationFrame方法即時更新繪制情況。這個方法與刷新率有關,看看mdn上面怎么說的:
window.requestAnimationFrame() 方法會告訴瀏覽器你希望執行一個動畫。它要求瀏覽器在下一次重繪之前,調用用戶提供的回調函數。
對回調函數的調用頻率通常與顯示器的刷新率相匹配。雖然 75hz、120hz 和 144hz 也被廣泛使用,但是最常見的刷新率還是 60hz(每秒 60 個周期/幀)。為了提高性能和電池壽命,大多數瀏覽器都會暫停在后臺選項卡或者隱藏的 <iframe> 中運行的 requestAnimationFrame()。
本示例中,更新指針的位置并不需要很高的刷新頻率,可以通過節流進行一下優化:
var fps = 5, fpsInterval = 1000 / fps,lastTime = new Date().getTime(); //記錄上次執行的時間
function runStep() {
requestAnimationFrame(runStep);
var d=new Date(),now = d.getTime()
var elapsed = now - lastTime;
if (elapsed > fpsInterval) {
ctxUI.clearRect(0,0,oW,oH);
lastTime = now - (elapsed % fpsInterval);
//度數從0開始,而0在3刻度(15分/秒位置),修正為全值-15,如果小于0則用60減回
var hour=d.getHours(),minute=d.getMinutes()-15,second=d.getSeconds()-15;//console.log(d.getSeconds(),second);
hour=hour>11? hour-15 : hour-3;
drawHp(hour>=0? hour : 12+hour,minute+15,second+15);
drawMp(minute>=0? minute : 60+minute,second+15);
drawSp(second>=0? second : 60+second);
}
}
runStep();
當然,實現時鐘的方法是很多,比如可以使用畫布的旋轉(rotate方法)來實現指針的動態轉動等等。
完整HTML+JS源碼:
先貼上另一位開發者的原文地址,其實里面顯示的是2種風格的時鐘,一種為傳統的掛鐘,一種為數字時鐘,我就分開來顯示了。這里再另外改了個不同背景色的方形時鐘,對于數字時鐘也進行了改進。
在最后會放出源碼,給喜歡研究的小伙伴一個參考。當然咯,最好還是自己能實踐一下。
此教程版本是基于原文地址基礎上進行小的修改而來,使用的是LESS的Mixin代碼方式,使得后期調整大小及顏色會更加方便,只需要調整不同參數即可。
如果你對LESS以及mixin不太了解,建議先學習基礎知識。less編譯css的軟件,推薦使用koala。
結構如上圖所示,CSS里創建style.less就可以了(編譯引用會生成css文件),另外創建resource文件夾,里面可以再創建mixin_clock.less(不需要編譯),文件起名可以根據自己的項目需求。clock.html中正常引用style.css文件就可以了。
把css目錄拖到koala軟件中,并且開啟style.less右邊的source map,這樣在瀏覽器上,f12可以看到對應的代碼位置,方便調整。
style.less里的引用代碼,編譯后就可以自動生成同名.css文件了:
//公共文件夾根目錄
@resource_path: '../resource';
// 組件擴展
@import '@{resource_path}/mixin_clock';
等以后resource里組件多的話,也可以單獨留一個引用的文件。接下來就可以正式開工了。
原來的css樣式的部分,全都放在mixin_clock.less文件中,因為是引用并且一直在編譯的,所以都能正常顯示。
這里要提幾點順便的調整
1、border-radius,如果是正圓的,則改為50%,而不是具體的數值。
2、background: linear-gradient(top, #f9f9f9, #666),里面的top,改為180deg,因為在部分chrome中可能會報錯,而具體的角度不會
3、有些div用了position: absolute,就順便加上z-index值,具體數字,根據層疊的前后進行設置
4、將最后的數字時鐘和掛鐘拆分(如果你想和在一起的話,建議改為年月日可能更實用)
使用less有個好處就是不需要反復寫父級名稱,部分的修改基礎結構如下:
// 表盤
.frame_face {
...
&:before {
...
}
&:before {
...
}
}
tips: 因為要集成到別的框架中,自己定義的名稱,建議統一改用下劃線,以作區分。
這里的&,相當于.frame_face:before{}
這一步比較重要,這也是LESS比寫標準CSS最顯著的優勢,當然現在CSS也可以寫變量,但是遠沒有LESS寫的方便。
將里面一些需要以后調整的都提取出來作為變量,我也大致羅列下調整的地方:
1、比如鐘的大小,如果調整的話,里面的大小也都需要跟著調整,所以上面提到最好是按百分比作為相對的數值,那么調整一個地方,相對的部分也能跟著進行調整。
2、涉及到的顏色,比如背景色,文字顏色等。當然咯這里涉及的地方比較多,并非所有的都需要提取出來,根據自己的需求即可。
3、倒角數值也可以取出來,比如最終需要一個方形的時鐘,那就改成數值就可以了。
4、改為Mixin版,以方便參數調用,為了便于區分,可以前綴加上mixin,格式參考:
.mixin_basic_clock(變量名1: 參數; 變量名2: 參數){
代碼部分1: 變量名1;
代碼部分2: 變量名2;
}
其實這個改動不難,并且對數字時鐘增加了年月日周。
原來的每個公共的判斷方法提取出來,因為一般都是顯示2位數,原來的小于2位,就自動在前面加個“0”,改進如下
function checkTime (i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
hour = checkTime(hour);
minute = checkTime(minute);
second = checkTime(second);
clock.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>時鐘</title>
<link href="../css/style.css" rel="stylesheet" />
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="../js/clock.js"></script>
</head>
<body>
<div class="circle_clock">
<!-- 圓形掛鐘表盤 -->
<div class="frame_face">
<!-- 刻度 -->
<ul class="minute_marks"></ul>
<!-- 刻度數字 -->
<ul class="digits">
<li>3</li>
<li>5</li>
<li>9</li>
<li>12</li>
</ul>
<!-- 指針 -->
<div class="hours_hand"></div>
<div class="minutes_hand"></div>
<div class="seconds_hand"></div>
<!-- 指針中心點 -->
<div class="clock_center"></div>
</div>
</div>
<div class="squire_clock">
<!-- 方形掛鐘表盤 -->
<div class="frame_face">
<!-- 刻度 -->
<ul class="minute_marks"></ul>
<!-- 刻度數字 -->
<ul class="digits">
<li>3</li>
<li>6</li>
<li>9</li>
<li>12</li>
</ul>
<!-- 指針 -->
<div class="hours_hand"></div>
<div class="minutes_hand"></div>
<div class="seconds_hand"></div>
<!-- 指針中心點 -->
<div class="clock_center"></div>
</div>
</div>
<br>
<br>
<!-- 數字時鐘 -->
<div class="digital_clock">
<div class="digit_ymd num"></div>
<div class="digit_hms num"></div>
</div>
</body>
</html>
mixin_clock.less
//傳統掛鐘
//@clock_wh: 鐘的寬度/高度
//@clock_border: 鐘的邊框,50%為圓形,也可以設置成具體數值
//@frame_bgc1: 表盤背景漸變色1
//@frame_bgc2: 表盤背景漸變色2
//@mm_bgc: 刻度背景色
//@digits_c: 表盤數字文字顏色
//@hh_bgc: 時針背景顏色
//@mh_bgc:分針背景顏色
//@sh_bgc:秒針背景顏色
.mixin_basic_clock(@clock_wh: 30em; @clock_border: 50%; @frame_bgc1:#fff; @frame_bgc2:#ccc; @mm_bgc: #666; @digits_c: #555; @hh_bgc:#232425; @mh_bgc: #343536; @sh_bgc: #c00) {
//@digits: 表盤文字中心距離
//@digits_s: 表盤文字大小
//@clock_center: 表盤中心大小
@digits: @clock_wh / 4.2;
@digits_s: @clock_wh / 20;
@clock_center: @clock_wh / 8;
// 表盤
.frame_face {
position: relative;
width: @clock_wh;
height: @clock_wh;
border-radius: @clock_border;
background: linear-gradient(180deg, #f9f9f9, #666);
box-shadow: 0.5em 0.5em 4em rgba(0, 0, 0, 0.8);
&:before {
content: '';
width: @clock_wh * 0.98;
height: @clock_wh * 0.98;
border-radius: @clock_border;
position: absolute;
top: @clock_wh * 0.01;
left: @clock_wh * 0.01;
background: radial-gradient(
ellipse at center,
rgba(246, 248, 249, 1) 0%,
rgba(229, 235, 238, 1) 65%,
rgba(205, 212, 217, 1) 66%,
rgba(245, 247, 249, 1) 100%
);
}
&:after {
content: '';
width: @clock_wh * 0.94;
height: @clock_wh * 0.94;
border-radius: @clock_border;
position: absolute;
top: @clock_wh * 0.03;
left: @clock_wh * 0.03;
box-shadow: inset rgba(0, 0, 0, 0.2) 0.2em 0.2em 1em;
// border: (@clock_wh * 0.001) solid rgba(0, 0, 0, 0.2);
background: linear-gradient(180deg, @frame_bgc1, @frame_bgc2);
}
}
// 刻度
.minute_marks li {
display: block;
width: 0.2em;
height: 0.6em;
background: @mm_bgc;
position: absolute;
top: 50%;
left: 50%;
margin: -0.4em 0 0 -0.1em;
z-index: 8;
}
// 刻度數字
.digits {
width: @clock_wh;
height: @clock_wh;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
margin-top: -@clock_wh / 2;
margin-left: -@clock_wh / 2;
padding: 0;
z-index: 9;
li {
font-size: @digits_s;
display: block;
width: @digits_s;
height: @digits_s;
position: absolute;
top: 50%;
left: 50%;
line-height: @digits_s;
text-align: center;
margin: (-@digits_s / 2) 0 0 (-@digits_s / 2);
font-weight: bold;
color: darken(@digits_c, 10%);
&:nth-child(1) {
transform: translate(@digits, 0);
}
&:nth-child(2) {
transform: translate(0, @digits);
}
&:nth-child(3) {
transform: translate(-@digits, 0);
}
&:nth-child(4) {
transform: translate(0, -@digits);
}
}
}
// 時針
.hours_hand {
width: 0.8em;
height: 7em;
border-radius: 0 0 0.9em 0.9em;
background: @hh_bgc;
position: absolute;
bottom: 50%;
left: 50%;
margin: 0 0 -0.8em -0.4em;
box-shadow: @hh_bgc 0 0 2px;
transform-origin: 0.4em 6.2em;
transform: rotate(-25deg);
z-index: 21;
&:before {
content: '';
background: inherit;
width: 1.8em;
height: 0.8em;
border-radius: 0 0 0.8em 0.8em;
box-shadow: @hh_bgc 0 0 1px;
position: absolute;
top: -0.7em;
left: -0.5em;
}
&:after {
content: '';
width: 0;
height: 0;
border: 0.9em solid @hh_bgc;
border-width: 0 0.9em 2.4em 0.9em;
border-left-color: transparent;
border-right-color: transparent;
position: absolute;
top: -3.1em;
left: -0.5em;
}
}
// 分針
.minutes_hand {
width: 0.6em;
height: 12.5em;
border-radius: 0.5em;
background: @mh_bgc;
position: absolute;
bottom: 50%;
left: 50%;
margin: 0 0 -1.5em -0.3em;
box-shadow: @mh_bgc 0 0 2px;
transform-origin: 0.3em 11em;
z-index: 22;
}
// 秒針
.seconds_hand {
width: 0.2em;
height: 14em;
border-radius: ~'0.1em 0.1em 0 0 / 10em 10em 0 0';
background: @sh_bgc;
position: absolute;
bottom: 50%;
left: 50%;
margin: 0 0 -2em -0.1em;
box-shadow: rgba(0, 0, 0, 0.8) 0 0 0.2em;
transform-origin: 0.1em 12em;
z-index: 23;
&:before {
content: '';
width: 0.6em;
height: 3em;
border-radius: ~'0.2em 0.2em 0.4em 0.4em / 0.2em 0.2em 2em 2em';
box-shadow: rgba(0, 0, 0, 0.8) 0 0 0.2em;
background: inherit;
position: absolute;
left: 50%;
bottom: -3em;
margin-left: -0.3em;
}
&:after {
content: '';
width: 1em;
height: 1em;
border-radius: 50%;
background: inherit;
position: absolute;
left: 50%;
bottom: 1.5em;
margin-left: -0.5em;
}
}
//中心點
.clock_center {
&:before {
content: '';
width: 1.6em;
height: 1.6em;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
margin: -0.8em 0 0 -0.8em;
background: #121314;
z-index: 10;
}
&:after {
content: '';
width: @clock_center;
height: @clock_center;
border-radius: 50%;
position: absolute;
top: 50%;
left: 50%;
margin: (-@clock_center / 2) 0 0 (-@clock_center / 2);
border: 0.1em solid #c6c6c6;
background: radial-gradient(
ellipse at center,
rgba(200, 200, 200, 0),
rgba(190, 190, 190, 1) 90%,
rgba(130, 130, 130, 1) 100%
);
z-index: 11;
}
}
}
// 數字時鐘
//@clock_w: 時鐘寬度
//@clock_fs1: 文字大小1
//@clock_fs2: 文字大小2
//@clock_bgc1: 時鐘背景色1
//@clock_bgc2: 時鐘背景色2
//@clock_fc: 時鐘文字顏色
.mixin_digital_clock(@clock_w: 30em; @clock_fs1: 2em; @clock_fs2: 5em; @clock_bgc1:#0a2e38; @clock_bgc2:#000; @clock_fc: #daf6ff) {
width: @clock_w;
border-radius: 0.6em;
padding: 1em;
overflow: hidden;
background: @clock_bgc1;
background: radial-gradient(ellipse at center, @clock_bgc1 0%, @clock_bgc2 70%);
.num {
padding: 0.1em;
color: @clock_fc;
text-align: center;
word-break: keep-all;
letter-spacing: 0.05em;
font-family: 'Share Tech Mono', Consolas, monaco, monospace;
text-shadow: ~'0 0 20px #0aafe6, 0 0 20px rgb(10 175 230 / 0%)';
}
.digit_ymd {
font-size: @clock_fs1;
}
.digit_hms {
font-size: @clock_fs2;
}
}
style.less
//公共文件夾根目錄
@resource_path: '../resource';
// 組件擴展
@import '@{resource_path}/mixin_clock';
//圓形掛鐘
.circle_clock {
.mixin_basic_clock();
display: inline-block;
margin: 2em;
}
//方形掛鐘
.squire_clock {
.mixin_basic_clock(@clock_border: 2em; @frame_bgc1:#90bef3; @frame_bgc2:#616fad; @mm_bgc: #333;);
display: inline-block;
margin: 2em;
}
//數字時鐘
.digital_clock {
.mixin_digital_clock();
margin: 2em;
}
clock.js
window.onload = function () {
// 生成刻度
var markWrap = $('.minute_marks');
for (index = 0; index < 60; index++) {
var markItem = $('<li></li>');
markItem.css("transform", "rotate(" + index * 6 + "deg) translateY(-12.7em)");
if (index % 5 == 0) {
markItem.css({ "width": "0.3em", "height": "1em" });
}
markWrap.append(markItem);
}
setInterval(function () {
var today = new Date();
var year = today.getFullYear();
var month = today.getMonth() + 1;
var date = today.getDate();
var week = "星期" + "日一二三四五六".split(/(?!\b)/)[today.getDay()];
var hour = today.getHours();
var minute = today.getMinutes();
var second = today.getSeconds();
var hournum;
// 指針轉動
if (hour > 12) {
hournum = ((hour - 12) + minute / 60) * 30;
} else {
hournum = (hour + minute / 60) * 30;
}
var minnum = (minute + second / 60) * 6 + second / 60;
var sennum = second * 6;
$('.hours_hand').css('transform', 'rotate(' + hournum + 'deg)');
$('.minutes_hand').css('transform', 'rotate(' + minnum + 'deg)');
$('.seconds_hand').css('transform', 'rotate(' + sennum + 'deg)');
// 數字時鐘
function checkTime (i) {
if (i < 10) {
i = "0" + i;
}
return i;
}
month = checkTime(month);
date = checkTime(date);
hour = checkTime(hour);
minute = checkTime(minute);
second = checkTime(second);
$('.digit_ymd').text(year + '/' + month + '/' + date + ' ' + week);
$('.digit_hms').text(hour + ':' + minute + ':' + second);
}, 1000);
}
時鐘的樣式還可以有更豐富的方法,比如給掛鐘加個背景,8字形的數字時鐘等等,可以在原有引用mixin之后再自己加樣式覆蓋,更多創意等待你的發現
擊查看時鐘特效
對于javascript特效的學習,重要的是邏輯思路,所以這個時鐘特效不是很華麗,但是功能都展現出來了,而學習javascript并不是單純的扣代碼,很多人都覺得,摳完代碼,能看懂了,就算是學會了,但是,說的難聽點這樣的學習方式其實是自斷前程的學習方法,若是一門月薪過萬的技術有那么簡單學習,那么怎么還會有那么多人找不到工作呢?學習javascript特效最重要的是仔細研究一個特效的思路方法,然后根據這個特效可以擴展最初其他類似功能或者更復雜的特效,才算徹底的掌握好了這方面的知識!我的頭條號里面也有許多華麗的特效以及HTML5/javascript游戲,有興趣的朋友可以去看看!文末附上本次javascript時鐘的源碼!
如果想要更多的企業求職加分項目,案例,學習方法可以來一下我的前端群570946165,每天都會精挑細選一個特效,項目出來詳細講解,分享!包括答疑解惑!
代碼過長需要文檔版源碼來我的前端群570946165,已上傳到群文件
頭條號里有許多web前端學習視頻/源碼,企業常用特效/案例/項目,敬請關注!
*請認真填寫需求信息,我們會在24小時內與您取得聯系。