基于Canvas的Html5多時區(qū)動態(tài)時鐘實(shí)戰(zhàn)代碼

前言
出差旅行相信大家一定會住酒店,大家在酒店的前臺進(jìn)行預(yù)訂的時候,是不是都會留意。通常在大堂的前方會有一面時鐘,大概是下面這種樣子:
這里只是一個截圖,其實(shí)不太完整。上面詳細(xì)的羅列了巴黎、北京、紐約、倫敦、莫斯科、東京等城市的時間。 通常來說,之所以要展示這么多的時鐘,一般是對外的酒店,所面向的客人很多都是外國人,他們來自于四面八方,需要將時間和自己國家的時間一致,也是對時間同步的一種保障,這是一種服務(wù)力的體現(xiàn)。
當(dāng)然,上面這種是實(shí)體的鐘,需要實(shí)體鐘表的采購成本?,F(xiàn)在電子屏已經(jīng)很常見也很普及,那么有沒有可能將Web界面投放到電子屏中,實(shí)現(xiàn)電子鐘的web化展示,加上前端的樣式控制,應(yīng)該也是可以滿足酒店等場所的顯示需求。也因此有了本文和相關(guān)的程序設(shè)計。
本文即以Canvas為基礎(chǔ),以支持多時區(qū)的多時鐘的動態(tài)Web展示為例。實(shí)現(xiàn)一種在Html5上的電子鐘展示方法,首先介紹Canvas是什么,然后具體介紹如何進(jìn)行時鐘的繪制,其次介紹時鐘的多時區(qū)支持,最后給出運(yùn)行的實(shí)際效果。通過本文可以了解Canvas的詳細(xì)用法,掌握基本的文本繪制、樣式控制、屬性管理的基本知識,通過多時鐘的展示場景,將各個知識點(diǎn)融會貫通。如果您想了解Canvas的使用方法,可以來這里看看,有什么疑問的也可以在評論區(qū)留言交流。
一、關(guān)于Canvas技術(shù)
雖然Canvas不是最新的技術(shù),相信很多朋友也不是很熟悉,因此本節(jié)還是花一點(diǎn)時間簡單的將Canvas的知識做個介紹,讓大家有個基本的了解,為下一節(jié)內(nèi)容的講解打下基礎(chǔ)。主要包含三個部分,首先介紹canvas是什么,然后介紹它的語法。更詳細(xì)的內(nèi)容,大家可以去看html的教程,上面有詳細(xì)的描述。
1、Canvas是什么
Canvas API(畫布)是在HTML5中新增的標(biāo)簽用于在網(wǎng)頁實(shí)時生成圖像,并且可以操作圖像內(nèi)容,基本上它是一個可以用JavaScript操作的位圖(bitmap)。Canvas 對象表示一個 HTML 畫布元素 -<canvas>。<canvas> 標(biāo)記由 Apple 在 Safari 1.3 Web 瀏覽器中引入。對 HTML 的這一根本擴(kuò)展的原因在于,HTML 在 Safari 中的繪圖能力也為 Mac OS X 桌面的 Dashboard 組件所使用,并且 Apple 希望有一種方式在 Dashboard 中支持腳本化的圖形。Firefox 1.5 和 Opera 9 都跟隨了 Safari 的引領(lǐng)。這兩個瀏覽器都支持 <canvas> 標(biāo)記。我們甚至可以在 IE 中使用 <canvas> 標(biāo)記,并在 IE 的 VML 支持的基礎(chǔ)上用開源的 JavaScript 代碼(由 Google 發(fā)起)來構(gòu)建兼容性的畫布。<canvas> 的標(biāo)準(zhǔn)化的努力由一個 Web 瀏覽器廠商的非正式協(xié)會在推進(jìn), <canvas> 已經(jīng)成為 HTML 5 草案中一個正式的標(biāo)簽。
在現(xiàn)代 Web 開發(fā)中,開發(fā)者們更多的會借助 Canvas 提供的API去繪制上下文,可以自由繪制各種2D和3D圖形,創(chuàng)建富有視覺沖擊力的游戲場景和角色。Canvas的使用可以使得游戲能夠?qū)崿F(xiàn)流暢的動態(tài)效果和用戶交互。無論是簡單的小游戲還是復(fù)雜的游戲引擎,Canvas 都被廣泛應(yīng)用。
在WebGIS開發(fā)當(dāng)中,canvas也是一個非常重要的展示場景,比如我們之前用過的動態(tài)標(biāo)繪組件,也是基于Canvas來實(shí)現(xiàn)的,它的性能是非常高的。不管是面向2D還是3D的場景,canvas都有用武之地。
2、Canvas的屬性及渲染特性
Canvas的屬性比較簡單,而且它的屬性比較簡單,跟普通的Html標(biāo)簽的屬性是一致的,也可以使用如ID、高度和寬度這幾個屬性。其作用就不再贅述,比較簡單。canvas的強(qiáng)大還是取決于它的渲染特性,因此這里簡單介紹一下Canvas的渲染特性。
說高性能渲染時得說說DOM駐留模式和Canvas快速模式。
DOM駐留模式:一種基于文檔對象模型(DOM)的渲染技術(shù)。在DOM駐留模式下,頁面的布局和樣式是由DOM樹來掌管的。當(dāng)頁面需要更新時,瀏覽器會重新計算布局和樣式并重新渲染。此模式非常靈活,特別適用于處理動態(tài)頁面交互和多樣化的樣式控制。
Canvas快速模式:利用HTML5的Canvas元素進(jìn)行圖形渲染。開發(fā)者可以使用Canvas提供的2D或3D繪圖API直接在畫布上繪制圖形。相比于DOM駐留模式,Canvas快速模式更加高效。它不關(guān)心頁面的布局和樣式,而是在需要時只重繪受影響的部分。
分層提高Canvas性能:可以進(jìn)一步提升Canvas性能的策略,即對變化較少和變化較多的內(nèi)容進(jìn)行分開渲染。它能夠顯著降低完全沒有必要的渲染性能開銷。分層渲染的思想被廣泛應(yīng)用于各種圖形相關(guān)的領(lǐng)域,從古老的皮影戲、套色印刷術(shù),到現(xiàn)代電影/游戲工業(yè)以及虛擬現(xiàn)實(shí)領(lǐng)域等等。
上面簡單的對Canvas的相關(guān)知識進(jìn)行簡單介紹,有了上述的基本知識,下面結(jié)合實(shí)例講解Canvas的多時區(qū)時鐘動態(tài)展示。
二、Canvas動態(tài)多時區(qū)展示
在了解Canvas的基本知識以后,我們來介紹Canvas的基本使用。在這個實(shí)例中,我們需要在Html5頁面中,使用Canvas繪制6個不同城市的時鐘,并且要在時鐘上標(biāo)注是屬于哪個城市,其對應(yīng)的24小時制時間是多少,同時時鐘要可以動態(tài)轉(zhuǎn)動。本節(jié)即以詳細(xì)代碼的形式進(jìn)行講解。
1、新建html頁面
Canvas也是建立在Html頁面上的組件,因此想要把Canvas渲染出來,就一定要創(chuàng)建展示的基礎(chǔ)。新建一個html文件,關(guān)鍵代碼如下所示:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Canvas 多時區(qū)時鐘可視化</title> <style> body { background-color: #F5F5F5; } canvas { border: 1px dashed #444; } </style> </head> <body> <table style="width:99%;margin: auto;align:center;"> <tbody> <tr> <td > <canvas id="clock0" width="300" height="300"></canvas> </td> <td> <canvas id="clock1" width="300" height="300"></canvas> </td> <td> <canvas id="clock2" width="300" height="300"></canvas> </td> </tr> <tr> <td> <canvas id="clock3" width="300" height="300"></canvas> </td> <td> <canvas id="clock4" width="300" height="300"></canvas> </td> <td> <canvas id="clock5" width="300" height="300"></canvas> </td> </tr> </tbody> </table> </body> </html>
這里僅展示Canvas的功能API,對于頁面的特效樣式?jīng)]有做過多的設(shè)置,如果是真實(shí)項目,建議在這個基礎(chǔ)上狠狠地記性樣式的修改,改造成符合項目需要的美觀的。上面采用table布局,為了展示6個不同城市的時鐘,我們使用兩行三列的布局模式,每個單元格展示一個時鐘。為了實(shí)現(xiàn)動態(tài)的控制這些時鐘,比如第一個時鐘用來顯示紐約的時間,因此有必要使用id對每個canvas進(jìn)行分別定義。
2、創(chuàng)建Canvas對象
在創(chuàng)建了html頁面展示元素之后,我們還需要使用canvas來繪制時鐘的效果,為了能實(shí)現(xiàn)時鐘的動態(tài)效果,我們將canvas的id屬性從0-5分別設(shè)置為clock0-clock5,分別用來代表"紐約","倫敦","巴黎","莫斯科","北京","東京"這五個不同時區(qū)的城市。為了在后面的時間繪制中能精準(zhǔn)控制,我們將所有的Canvas創(chuàng)建出來之后,設(shè)置到對應(yīng)的數(shù)組當(dāng)中。
//創(chuàng)建時鐘數(shù)組 var clockArray = new Array(); var timeZoneArray = ["紐約","倫敦","巴黎","莫斯科","北京","東京"]; for(var i = 0;i < 6; i++){ const canvas = document.getElementById("clock" + i); const ctx = canvas.getContext("2d"); const centerX = canvas.width / 2; const centerY = canvas.height / 2; // 將坐標(biāo)系移動到中心點(diǎn) ctx.translate(centerX, centerY); clockArray.push(canvas); }
3、繪制所有的時鐘
將Canvas創(chuàng)建出來后,就可以進(jìn)行時鐘的繪制了。下面將結(jié)合源碼來詳細(xì)介紹如何進(jìn)行時鐘的繪制。
function drawClock() { const now = new Date(); for(var j = 0;j < 6;j++){ var _canvas = clockArray[j]; var _ctx = _canvas.getContext("2d"); const radius = _canvas.width / 2 - 5; const centerX = _canvas.width / 2; const centerY = _canvas.height / 2; _ctx.clearRect(-centerX, -centerY, _canvas.width, _canvas.height); // 每次繪制前清空整個畫布 _ctx.beginPath(); _ctx.arc(0, 0, radius, 0, 2 * Math.PI); _ctx.stroke(); // 繪制鐘表數(shù)字 _ctx.textAlign = "center"; _ctx.textBaseline = "middle"; _ctx.font = "20px sans-serif"; var text = timeZoneArray[j]; _ctx.strokeText(text + "時間", 2, - 80); _ctx.font = "bold 14px Arial"; drawClockNumber(_ctx,radius);//繪制數(shù)字 // 繪制時針 var bjHour = now.getHours(); //獲取小時 var hour = getHour(j,bjHour); var minute = now.getMinutes(); var second = now.getSeconds(); drawShowTime(_ctx,hour,minute,second);//繪制當(dāng)前時間 var hourAngle = (hour % 12 + minute / 60 + second / 3600) * Math.PI / 6; var hourLength = 0.6 * radius; var hourX = Math.sin(hourAngle) * hourLength; var hourY = -Math.cos(hourAngle) * hourLength; _ctx.beginPath(); _ctx.moveTo(0, 0); _ctx.lineTo(hourX, hourY); _ctx.lineWidth = 4; _ctx.lineCap = "round"; _ctx.stroke(); // 繪制分針 const minuteAngle = (minute + second / 60) * Math.PI / 30; const minuteLength = 0.8 * radius; const minuteX = Math.sin(minuteAngle) * minuteLength; const minuteY = -Math.cos(minuteAngle) * minuteLength; _ctx.beginPath(); _ctx.moveTo(0, 0); _ctx.lineTo(minuteX, minuteY); _ctx.lineWidth = 2; _ctx.stroke(); // 繪制秒針 const secondAngle = second * Math.PI / 30; const secondLength = 0.9 * radius; const secondX = Math.sin(secondAngle) * secondLength; const secondY = -Math.cos(secondAngle) * secondLength; drawScale(_ctx,radius);//繪制刻度 _ctx.beginPath(); _ctx.moveTo(0, 0); _ctx.lineTo(secondX, secondY); _ctx.lineWidth = 1; _ctx.strokeStyle = "red"; // 設(shè)置顏色 _ctx.stroke(); // 繪制中央圓點(diǎn) _ctx.beginPath(); _ctx.arc(0, 0, 5, 0, 2 * Math.PI); _ctx.fillStyle = "#333"; // 設(shè)置顏色 _ctx.fill(); } // 循環(huán)繪制 setTimeout(drawClock, 1000); }
上面的代碼非常詳細(xì)的給出了時鐘的展示過程,下面將繪制的步驟進(jìn)行了簡單的介紹。
首先獲取canvas對象,并且清空畫布,因為時鐘每隔一秒即變化,同時分針秒針都要發(fā)生不斷地變化,這些就像橡皮擦一樣,要不斷擦除和不斷重新繪制。
然后在表盤中繪制具體是什么時間,比如北京時間,繪制后如下圖所示:
接下來就是繪制時鐘的數(shù)字刻度,比如1到12這幾個數(shù)字,如下圖所示:
//繪制刻度 function drawClockNumber(_ctx,radius){ for (let i = 1; i <= 12; i++) { var angle = i * Math.PI / 6; _ctx.rotate(angle); _ctx.translate(0, -radius + 15); _ctx.rotate(-angle); _ctx.fillText(i.toString(), 0, 0); _ctx.rotate(angle); _ctx.translate(0, radius - 15); _ctx.rotate(-angle) } }
繪制刻度的具體代碼:
// 繪制刻度 function drawScale(_ctx,radius){ // 假設(shè)最大刻度線長度是半徑的5% const maxMajorTickLength = radius * 0.05; // 較大刻度線長度 const maxMinorTickLength = radius * 0.025; // 較小刻度線長度 for (let m = 0; m < 60; m++) { // 計算每個刻度的角度 const minuteAngle = m * Math.PI / 30; // 根據(jù)分鐘數(shù)決定刻度線的長度 let tickLength; if (m % 5 === 0) { // 如果是每5分鐘的刻度,使用較大刻度線長度 tickLength = maxMajorTickLength; } else { // 否則使用較小刻度線長度 tickLength = maxMinorTickLength; } // 計算刻度線端點(diǎn)的坐標(biāo) var x1 = Math.sin(minuteAngle) * radius; // 圓邊緣的x坐標(biāo) var y1 = -Math.cos(minuteAngle) * radius; // 圓邊緣的y坐標(biāo) var x2 = Math.sin(minuteAngle) * (radius - tickLength); // 刻度線端點(diǎn)的x坐標(biāo) var y2 = -Math.cos(minuteAngle) * (radius - tickLength); // 刻度線端點(diǎn)的y坐標(biāo) // 繪制刻度線 _ctx.beginPath(); _ctx.moveTo(x1, y1); // 從圓邊緣開始 _ctx.lineTo(x2, y2); // 向內(nèi)延伸到刻度線端點(diǎn) _ctx.stroke(); } }
在繪制刻度的這里,我剛開始一直沒成功,主要原因是沒掌握方法,刻度的兩個起始點(diǎn)沒繪制準(zhǔn)確,因此導(dǎo)致了刻度繪制一直不準(zhǔn)確,請記得一定計算好位置,尤其是使用moveTo和lineTo兩個方法類調(diào)整,主要刻度從圓邊緣開始,而不要movoTo(0,0),這樣從圓心開始,繪制出來的效果就不對了。
由于這6個城市分別屬于6個不同的時區(qū),因此也就造成了這6個城市的時間是不一樣的,也就是我們常說的時差,通過查找資料可以知道,這里每個城市的時差大約是如下代碼表示的。
function getHour(index,bjHour){ var hour = bjHour; // bjHour是北京時間的小時數(shù) var offset; // 定義時區(qū)偏移量 // 根據(jù)時區(qū)索引計算偏移量 switch(index) { case 0: // 紐約 (北京時間比紐約快13小時) offset = -13; break; case 1: // 倫敦 (北京時間比倫敦快8小時) offset = -8; break; case 2: // 巴黎 (北京時間比巴黎快7小時) offset = -7; break; case 3: // 莫斯科 (北京時間比莫斯科快5小時) offset = -5; break; case 4: // 北京 (默認(rèn)為北京時間) offset = 0; break; case 5: // 東京 (假設(shè)北京時間比東京慢1小時) offset = 1; break; default: // 如果索引不在預(yù)期范圍內(nèi),返回原始小時數(shù) return hour; } // 應(yīng)用時區(qū)偏移量,并確保小時數(shù)在0到23之間 hour += offset; hour = (hour + 24) % 24; // 循環(huán)處理,確保結(jié)果在24小時制內(nèi) return hour; }
這里通過計算偏移量的方式來計算城市的時間,剛開始沒有注意,這樣計算出來的結(jié)果,會有不準(zhǔn)確,因此才采用了時區(qū)偏移的處理方式,這樣出來能保證每個時鐘都是24小時之內(nèi)。當(dāng)然,為了計算方便,您也可以直接使用我上面的轉(zhuǎn)換邏,是可以直接使用的。
經(jīng)過上面的代碼,就可以實(shí)現(xiàn)時鐘的動態(tài)展示。效果如下所示:
總結(jié)
以上就是本文的主要內(nèi)容,本文以Canvas為基礎(chǔ),支持多時區(qū)的多時鐘的動態(tài)Web展示為例實(shí)現(xiàn)一種在Html5上的電子鐘展示方法,首先介紹Canvas是什么,然后具體介紹如何進(jìn)行時鐘的繪制,其次介紹時鐘的多時區(qū)支持,最后給出運(yùn)行的實(shí)際效果。通過本文可以了解Canvas的詳細(xì)用法,掌握基本的文本繪制、樣式控制、屬性管理的基本知識,通過多時鐘的展示場景,將各個知識點(diǎn)融會貫通。如果您想了解Canvas的使用方法,可以來這里看看。行文倉促,定有諸多不足之處,歡迎各位專家朋友有什么疑問的也可以在評論區(qū)留言交流。
為方便朋友們學(xué)習(xí),源碼已經(jīng)上傳至資源,大家可以下載:源碼傳送地址。
到此這篇關(guān)于基于Canvas的Html5多時區(qū)動態(tài)時鐘實(shí)戰(zhàn)的文章就介紹到這了,更多相關(guān)html5 canvas時鐘內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持腳本之家!
相關(guān)文章
HTML5 Canvas 實(shí)現(xiàn)在線簽字功能(示例代碼)
在現(xiàn)代互聯(lián)網(wǎng)應(yīng)用中,有時我們需要讓用戶在網(wǎng)頁上進(jìn)行簽字操作,比如確認(rèn)文件、填寫電子表格或者簽署合同,利用 HTML5 的 canvas 畫布,我們可以輕松地實(shí)現(xiàn)這一功能,為用2024-06-19- 分時大盤回顧功能是一種用于分析股票行情的工具,本文就介紹一下HTML5 Canvas 繪制股市走勢圖,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)2023-04-25
HTML5 canvas實(shí)現(xiàn)的靜態(tài)循環(huán)滾動播放彈幕
這篇文章主要介紹了HTML5 canvas實(shí)現(xiàn)的靜態(tài)循環(huán)滾動播放彈幕,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來2021-01-05Html5基于canvas實(shí)現(xiàn)電子簽名并生成PDF文檔
這篇文章主要介紹了Html5基于canvas實(shí)現(xiàn)電子簽名并生成PDF文檔,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編2020-12-07- 這篇文章主要介紹了Html5 canvas畫圖白板踩坑,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-01
- 這篇文章主要介紹了基于html5 canvas做批改作業(yè)的小插件的相關(guān)資料,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參2020-05-20
html5 canvas 實(shí)現(xiàn)光線沿不規(guī)則路徑運(yùn)動
這篇文章主要介紹了html5 canvas 實(shí)現(xiàn)光線沿不規(guī)則路徑運(yùn)動,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-20HTML5 Canvas實(shí)現(xiàn)放大鏡效果示例
這篇文章主要介紹了HTML5 Canvas實(shí)現(xiàn)放大鏡效果示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)2020-03-25Html5 Canvas實(shí)現(xiàn)圖片標(biāo)記、縮放、移動和保存歷史狀態(tài)功能 (附轉(zhuǎn)換公
這篇文章主要介紹了Html5 Canvas實(shí)現(xiàn)圖片標(biāo)記、縮放、移動和保存歷史狀態(tài)功能 (附轉(zhuǎn)換公式),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借2020-03-18- 這篇文章主要介紹了詳解HTML5 Canvas標(biāo)簽及基本使用,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-10