2012/3/29

[CSS3] 使用 CSS3 製作 HTML 小時鐘

在 CSS3 中, 增加了一個 transform 功能, 使得我們可以對網頁元件進行放大、縮小、平移、旋轉、扭曲等等效果。我在本文中要介紹的是其中的 rotate 效果, 而且運用它來製作一個完全使用 HTML 標籤加上 CSS3, 不使用任何圖片的小時鐘。

在我開始介紹這個時鐘小工具之前, 你不妨往本網頁的右邊看一下, 在側邊欄的 jlClock 就是我的作品 (僅適用於 IE10、Chrome、FireFox、Opera 與 Safari 等瀏覽器; IE9 及以下版本不適用)。

工作原理

使用 transform: rotate 效果來製作時鐘是最適合的了。其工作原理相當直覺, 就是先把秒針、分針和時針畫在定位在同一個地方的 div 裡面, 然後利用 JavaScript 取出時間, 再依據當下的小時數、分鐘數以及秒數, 計算出應該讓時針、分針和秒針旋轉多少度, 就完成了。

我在程式中設計了一個 setInterval 指令, 每一秒觸發一次; 因此這個時鐘的誤差值低於一秒。在處理函式中, 我同時計算出秒針、分針和時針的旋轉角度, 並透過 jQuery 的 css 函式進行旋轉的動作。

我們看一下程式的部份:

var timerSecond = 0;
$(document).ready(function () {
    $(function () {
        timerSecond = self.setInterval('tickSecond()', 1000);
    });
});

function tickSecond() {
    var d = new Date();
    var sSec = d.getSeconds();
    var sMin = d.getMinutes();
    var sHr = d.getHours();
    if (sHr > 11) {
        $('#jlClockShowAm').hide();
        $('#jlClockShowPm').show();
    } else {
        $('#jlClockShowAm').show();
        $('#jlClockShowPm').hide();
    }
    var degSec = 'rotate(' + sSec * 6 + 'deg)';
    var degMin = 'rotate(' + (sMin * 6 + sSec * 0.1) + 'deg)';
    var degHr = 'rotate(' + ((sHr % 12) * 30 + sMin / 2) + 'deg)';
    $('#jlClockSecondArea').css('-webkit-transform', degSec);
    $('#jlClockMinuteArea').css('-webkit-transform', degMin);
    $('#jlClockHourArea').css('-webkit-transform', degHr);
};

程式的邏輯相當簡單, 應該沒有什麼需要特別說明的地方。為求簡化, 我只列出適用 Chrome 的部份 (即加上 "-webkit" 修飾詞之處)。

在設計這個小工具, 最困難的在於設定各元件大小, 以及如何對齊位置等等。但不管如何, 既然我已經都對好了, 你只要拿去用就行了 - 除非你要自己另外設計。

如果你要看完整程式的話, 我已經把它放在 jsFiddle 上面。你可以自己去檢查 HTML、CSS 和 JavaScript 等不同部份, 也可以自己試著進行修改。

令人意外的地方

在設計這個小工具時, 我倒是意外的發現一個奇怪的地方。我一開始的設計是像如下的樣子:

<div id="jlClockHourArea>
   <div id=jlClockHourPointer />
</div>
<div id="jlClockMinuteArea="">
   <div id="jlClockMinutePointer" />
</div>

如上, jlClockHourArea 和 jlClockMinuteArea 應該是沒有相干的兩個 div。但是, 如果我對前一個 div 進行 transform: rotate 指令之後, 第二個 div 竟然也會跟著被旋轉! 換句話說, 假設我對這兩個  div 旋轉了十度, 那麼第二個 div 結果是旋轉了二十度。

為克服這個問題, 你應該可以理解為何原始程式中為什麼每個 div 都又額外包了一層 div 了。

好用的 jsFiddle

這應該不是我第一次在文章裡面稱讚 jsFiddle 了。如果你已經在 jsFiddle 上建立了自己的 JavaScript 專案 (當然, 你也可以不寫任何一行 JavaScript), 按下 Save 之後, 你就取得了一個 jsFiddle 的網址 (例如本文原始檔的網址是 http://jsfiddle.net/JohnnyWorker/6mQzc/17/)。你可以再根據這個檔案自行修改, 然後按下 Update 按鈕, 得到更新的版本, 卻不用擔心把原來的檔案改壞了。

更棒的是, 你甚至可以把寫好的成果貼在自己的網頁上, 就像你在右側邊欄看到的那個 jlClock 一樣。這是怎麼辦到的呢? 方法很簡單, 以 jlClock 的網址 http://jsfiddle.net/JohnnyWorker/6mQzc/17/ 為例, 你只要在你的部落格或網頁中貼上如下的碼就可以了:

<iframe frameborder="0" src="http://jsfiddle.net/JohnnyWorker/6mQzc/17/show/light/" 
style="width: 200px; height: 200px;"></iframe>

當然, 你可以自己視狀況修改一些屬性, 例如 width 和 height 等等。原則上就是把原始網址加上 /show/light/ 字尾, 並包在 iframe 裡面即可 (這個網址不是每次都行得通; 貼上之前最好多試幾次)。當然, 缺點就是怕 jsFiddle 網站當掉或者出了什麼狀況 (經常發生), 所以你最好還是把它 host 在自己的網站上。

此外, 你可能會發現我在原始程式中把幾行註解掉了。這是因為我原本把時針和分針加上了環, 後來又覺得不好看, 卻捨不得拿掉。或許你可以自己試試能不能設計得更美觀一點。還有, 我在程式中保留了停止時鐘的方法; 這樣可以避免在開發時留下一些垃圾; 這功能在發行時就用不到了。

以下是完整的程式碼:

其實 rotate 可以用在很多類似的情境下, 例如 My Solar System 也是一個相當有趣的範例。連到該網頁後還有原始碼可以下載喔!

1 則留言: