BLOG

SVGでデジタル時計を実装してみた!

Written by XU

INDEX

アシスタントエンジニアのジョです。旧正月という「時間を大切にしたい」タイミングに、SVGでデジタル時計を実装してみました!

この実装、意外とシンプルだけどめっちゃ面白いです!

基本的なアイデアとしては、SVG の <polygon> を使ってデジタル時計を作り、数字ごとに 8 本の線(セグメント)を使って描画し、それを stroke-dasharray でコントロールする仕組みです!

解説

数字ごとに8本の線を定義

例えば「8」なら全部の線がオン、「1」なら2本だけオン、という感じです。

stroke-dasharray で線のオンオフを設定

配列 dasharrayData を用意して、数字ごとに「線を描く or 空白にする」のパターンを決めます!

setInterval で 1 秒ごとに時間を更新

JavaScript で new Date() を使って、現在の「時・分・秒」を取得しました!

各桁を数字ごとに分割し、該当する stroke-dasharraypolygon に適用します!

ちょっとした小技 & こだわりポイント

「stroke-dasharray」の使い方がポイント!

実際に動かしてみると、数字がスムーズに変わる感じが気持ちいいです!

例えば「5 60 5 0」を設定すると、「短い間隔+長い線+短い間隔」のリズムになって、視覚的にカッコいいです!

最初は stroke-dasharray の仕組みがわからなかったけど、試行錯誤しながら理解できる!

例えば 0 で始めると線がきれいにつながるし、間隔の長さを微調整すると見やすくなります!

デバッグしながら試していくのが楽しかったです~✨

実際のコード

実際のコードはこちら

document.addEventListener("DOMContentLoaded", () => {
    let polygons = [...document.querySelectorAll('polygon')];

    if (polygons.length === 0) {
        console.error("find no any <polygon> , pleas check your SVG code");
        return;
    }

    console.log("polygon sum:", polygons.length);

    polygons.forEach((poly, i) => {
        console.log(`Polygon ${i} total length:`, poly.getTotalLength());
    });

    let dasharrayData = [
        [0, 1, 1, 1, 1, 1, 1, 0], // 0
        [0, 0, 0, 1, 1, 0, 0, 0], // 1
        [1, 0, 1, 1, 0, 1, 1, 0], // 2
        [1, 0, 1, 1, 1, 1, 0, 0], // 3
        [1, 1, 0, 1, 1, 0, 0, 0], // 4
        [1, 1, 1, 0, 1, 1, 0, 0], // 5
        [1, 1, 1, 0, 1, 1, 1, 0], // 6
        [0, 0, 1, 1, 1, 0, 0, 0], // 7
        [1, 1, 1, 1, 1, 1, 1, 0], // 8
        [1, 1, 1, 1, 1, 1, 0, 0]  // 9
    ];

    dasharrayData = dasharrayData.map(arry => {
        let str = "0";
        arry.forEach(nums => {
            if (nums) str += ' 5 60 5 0';
            else str += ' 70 0';
        });
        return str;
    });

    // renew with in one sec.
    setInterval(() => {
        let now = new Date();
        let times = [
            Math.floor(now.getHours() / 10), now.getHours() % 10,
            Math.floor(now.getMinutes() / 10), now.getMinutes() % 10,
            Math.floor(now.getSeconds() / 10), now.getSeconds() % 10
        ];

        if (polygons.length !== times.length) {
            console.warn("polygon The quantity and the number of time digits do not match!");
            return;
        }

        polygons.forEach((ele, index) => {
            ele.style.strokeDasharray = dasharrayData[times[index]];
        });
    }, 1000);
});

シンプルだけど応用が効く仕組みなので、カスタマイズも色々できそうです!

他にも「アニメーションを加える」「フォントを変える」「背景を追加する」など、アイデア次第で拡張できるかもしれないです。

もし「SVG の stroke-dasharray って何?」と思ったら、試しに値を変えてみると理解しやすいです!

この方法なら、CSS だけでなく JavaScript でも色々コントロールできるから、汎用性高めます!

おまけ

「線の長さ」「ダッシュ間隔」「タイミング」を変えるだけで、まるで違う見た目になるので、ちょっとしたアートにも応用できるかもしれないです。

ぜひ試してみてくださいね!

参考文献

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/viewBox

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray

https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset

https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval

https://svg-animation-booklet.vercel.app/overview.html