HTML/CSS 入門 SVGを使ってタイマーを作成してみよう

今回はSVGを使って以下のようなタイマーを作ります。

流れ

以下が作成の流れです。

  • SVGを使って円を描く
  • JavaScriptを使って徐々にメーターを減らす表現をする

SVGを使って円を描く

まずはSVGを使って、以下のような円を描きます。

ソースコードは以下です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="svg001.css">
    <title>svg001</title>
</head>
<body>
    <svg height="100" width="100" id="svg001">
        <circle cx="50" cy="50" r="40"/>
    </svg>
</body>
</html>
svg {
    fill: none;
    stroke: lightgreen;
    stroke-width: 20;
    vertical-align: middle;
    stroke-dasharray: calc((40 * 2) * 3.14);
    stroke-dashoffset: 0;
}

stroke-dasharray について

stroke-dasharray によって円のborderを点線にしています。例えば、stroke-dasharray: 20; にすると、20pxの長さの点線になります。

今回、 calc((40 * 2) * 3.14) としていますが、これは点線の長さがちょうど円の一周の長さになるようになっています。

stroke-dashoffset について

そして、stroke-dashoffset は点線を始める位置を指定します。

今は0ですが、これを20にすると以下のようになります。

開始位置が20ずれることにより、点線がない部分(白い部分)ができました。

つまり、時間が経つごとに stroke-dashoffset の値を増やして開始地点をずらすことで、徐々に緑の部分がなくなることを表現できるわけです。

JavaScriptを使って徐々にメーターを減らす表現をする

最後にJavaScriptのsetIntervalを使って、1秒ごとに stroke-dashoffset を更新するようにします。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <link rel="stylesheet" href="svg001.css">
    <title>svg001</title>
</head>
<body>
    <svg height="100" width="100" id="svg001">
        <circle cx="50" cy="50" r="40"/>
    </svg>
    <script>
        const countDown = (targetEl, time) => {
          let offset = 0

          const timer = setInterval(() => {
            offset = offset + getStep(getLength(40), time)

            targetEl.style.strokeDashoffset = offset

            if(offset === getLength(40)) clearInterval(timer)
          }, 1000)

          const getLength = radius => (radius * 2) * 3.14
          const getStep = (length, time) =>  length / time
        }

        countDown(document.querySelector('#svg001'), 60)
    </script>
</body>
</html>

countDown 関数を定義しています。この関数には対象になるSVG要素を渡します。

現在の stroke-dashoffset の値は offset 変数に保持し、1秒ごとにこれを更新するような処理です。

SVGを使用するとよりいろいろなことができるので、是非触ってみてください。