【備忘録】JavaScript30 #2 時計
CSS編
divに時計らしい動きをさせる
(Transform Origin、Transform、Transition、および 3 次ベジェのトランジションタイミング関数)
00:00~00:51
3 つの個別の div があり、それぞれ時間、分、秒を表す
<div class="clock">
<div class="clock-face">
<div class="hand hour-hand"></div>
<div class="hand min-hand"></div>
<div class="hand second-hand"></div>
</div>
<div>
[音楽] 皆さんこんにちは、ウェス・ボスです。素晴らしい一日をお過ごしください。今日は、このとても素敵な CSS 時計を作成します。さて、これは JavaScript から現在時刻を取得し、表示されている現在の時、分、秒に基づいて、ここで実行されている針、秒針を更新します。それでは、ここで実行している HTML を見てみましょう。クロックのクラスを持つ div があります。ここにある円である時計の文字盤があり、針、針、針の 3 つの個別の div があり、これは時間、分、秒を表します。さあ、開けてみましょう。これが答えです。これは、この現実的なティックで目指していることのようなもので、これを実現するために重要な CSS を記述します。したがって、その部分は特に省略しました。
00:58~01:51
秒針(div)を動かす原点の変更:
これだけだと、円の中心ではなく秒針の真ん中を中心に回ってしまう。
transform: rotate(330deg); //330度傾ける
では、これがデフォルトの表示です。3 つの手の div があります。先に進み、この手の div を調べます。現在時刻が表示されます。では、どのように行うのでしょうか。ここに移動します。秒針を試してみましょう。変換、20 度回転とします。ここで問題となるのは、デフォルトでは、要素のちょうど真ん中で回転してしまうことです。ほとんどの場合、それがまさに必要なことです。しかし、この場合は、まったく必要なことではありません。やりたいことは、一番右側で回転させることです。ここの真ん中です。CSS の「.hand」の部分で、原点を変換します。
02:00~02:51
回転の基準を変える:
デフォルトの50%(要素の中心)から100%(要素の右端)に変更
transform-origin: 100%;
さらに12時の方向に向けるため、90度上に上げる
transform: rotate(90deg);
さて、原点は回転の基準になります。そこで、Transform Origin とします。ここでは 100% とします。これを x 軸に沿って行います。デフォルトでは 50% なので、これを 50% に変更して変換すると、原点から…この原点を移動すると、回転の基準が変わります。x 軸に沿って 100% にすると、ピボット ポイントは右端に配置されます。これが 100% に変更する理由です。これで、すべてをピボットできるようになります。もう 1 つの問題は、div がブロックであり、左から右にあるため、実際には 12:00 から開始されないことです。では、これをどのように行うのでしょうか。デフォルトでは、全体を 90 度回転させるだけで済みます。そこで、変換、回転、90 度と入力します。これで、すべての手が上と下を向いています。
03:01~03:49
トランジションを使うと自動で動いてくれる(transformで指示した動き)
transition: all 0.5s;
動き方も指定できる。滑らかな動きとか、グッと言ってちょっと戻る動きとか
transition-timing-fanction: ease-in-out; // 滑らか
transition-timing-fanction: cubic-bezier(0.1, 2.7,0.58. 1); // 開発者ツールで手動で設定。ちょっとバウンドしている
最後に、少しトランジションを適用します。ここに回転を設定すると、20 から 120、20 から 120 など、任意の数にすぐに切り替わります。ここで、トランジション、すべて、0.05 秒と設定できます。回転すると、自動的にトランジションが実行され、1 秒ごとに自動的に切り替わります。これでいいかもしれませんが、この機能のすばらしいところは、トランジション タイミング機能を使用して、イーズ イン アウトなど、任意のものを指定できることです。好きなものを選んで試すことができます。自動的にイーズ イン アウトする様子がわかりますか? これも気に入るかもしれません。ただし、この小さな 3 次ベジェ エディターをクリックすると、実際にかなり面白いものを作成できます。このようにジャッキ アップすると、変更すると、このティックが表示されます。前進したり後退したり、
04:00~04:36
では、このトランジションタイミング関数をポップインします。そして、これを 0.05 秒に下げて、素早く実行します。では、これを実行したときの様子を見てみましょう。Transform を実行しました。これで、カチカチ、カチカチ、カチカチ、カチカチという、すてきな、きびきびとした動きが得られます。まさに、私たちが求めていたものです。少し境界を越えてから、元に戻ります。これをすばやく実行したので、リアルなカチカチという動きが得られます。いいですね。これで、Transform Origin、Transform、Transition、および 3 次ベジェのトランジションタイミング関数を実行しました。では、これまでの更新を行う JavaScript を実際に記述してみましょう。まずは、最も頻繁に更新される秒針から始め、カチカチと動くのを確認します。
JavaScript編
04:44~05:22
秒針の実装。毎秒ごとに関数を実行する:
1000ミリ秒(1秒)ごとにsetDate()という自作の関数を実行
setInterval(setDate(), 1000);
現在時刻を取得:
function setDate() {
const now = new Date();
const seconds = now.getSeconds();
console.log(seconds); // 実際の秒数が毎秒表示される 56, 57, 58...
}
ティック、ティック、ずっと回ります。まず最初に、set date という関数を作成し、コンソールに「hi」とログ出力します。次に、どのくらいの頻度で実行するかです。そうですね、毎秒です。では、毎秒実行するにはどうすればよいでしょうか。set date という間隔を設定し、1000 ミリ秒ごとに実行します。それでは、うまく動作するか確認してみましょう。Hi、hi、hi、ok、よし。うまく動作しています。ただし、コンソールに hi とログ出力するのではなく、日付を取得します。const now は new date に等しいとします。秒は now ドット get seconds になります。コンソールに秒をログ出力します。56、57、58 です。これで現在の分の秒数が取得されます。
05:36~06:21
現在の秒数を度数に変換する:
ロジックの話。
現在56秒 ÷ 60秒 = 9.333… → 9.333… × 360 = 336度
const secondsDegrees = ((seconds / 60) * 360);
では、これを度数にするにはどうすればよいでしょうか。まず、これを 100 を底とする値に変換する必要があります。そうすると、0 では 0 度になります。100% では 360 度になります。ここで、const seconds degrees equals とします。秒を 60 で割ると、パーセンテージがわかります。これを 360 で掛けます。これがフルになるからです。つまり、60 を 60 で割ると、1 を 360 倍した値になり、360 度になります。そして、まだ選択していない秒針を取ります。選択できます。内側、外側などを選択して渡すこともできます。私は外側を選択して取得します。
06:29~07:12
要素を取得&transformさせる(=動かす)
(JavaScriptには「secondHand.style.transform」というものがあるのか〜)
const secondHand = document.querySelector('second-hand')
secondHand.style.transform = `rotate(${secondsDegrees})`; // さっき計算した度数に傾ける
ただし、関数の設計方法に応じて、それを渡すこともできます。つまり、const second hand equals document dot query selector とします。次に、その second hand を取得して、いくつかのスタイルを適用する必要があります。second hand dot style dot transform は、ES6 テンプレートリテラルを使用します。回転します。何度ですか? 通常は 100 度ですが、これは秒の度数になります。よし。これでほとんどのところまで到達できるはずです。どこにいるか確認してみましょう。わかりました。しかし、1 つ問題があります。ほぼ 60 秒ですが、まだ半分にも達していません。ここで問題になるのは、デフォルトでは左から右になっているのに、デフォルトでは上から下にしたいため、最初に 90 度オフセットしたことです。
07:23~08:15
90度遅い問題:
初期表示のdivの向きを12時に合わせるために横(左から右)から縦(上から下)にしたのが原因。
const secondsDegrees = ((seconds / 60) * 360) + 90; // +90を追記
必要なのは、これを括弧で囲んだだけです。ここで作業しているデフォルトの 90 度をオフセットするために 90 度を追加します。今どこまで進んでいるか見てみましょう。15、16 です。よし。では、ビデオを一時停止して、分と時間の両方を実行してみましょう。少し説明が不要かもしれませんが、自分で実行してみてください。そうでなければ、戻ってきて、残りは一緒にやってみましょう。const mins equals now dot get minutes とします。const mins degrees は、分を 60 で割った値に等しく、360 を 90 で掛けた値です。次に、秒針とします。ここでも、秒針、分針、そして時針も取得する必要があります。わかりました。次に、ここにいます。時針のドット スタイル ドット変換は、
08:33~09:20
分数の実装
const minsHand = document.querySelector('.min-hand'); // 分針の要素を取得
const mins = now.getMinuts(); // 現在の分数を取得
const minsDegrees = ((mins / 60) * 360) + 90; // 分数を度数に変換
minHand.style.transform = `rotate({$minDegrees}deg)`; // cssのtransform変更
同じものを、分度に置き換えます。見てみましょう。エディターが私に怒鳴っています。ここに何か忘れている。ああ、括弧を入れてください。ああ、問題があります。プロパティ変換を undefined に設定できません。スタイルを正しく綴らないと機能しません。綴り方を学んでください。これでできました。これら 2 つは両方とも機能しています。実際に機能するかどうかを確認するには、1 分待つ必要があります。最後に、時間針を取ります。60 ではなく 12 で割ります。次に、時針を取ります。おっと。これは時針ですが、これは分針のはずです。分針です。そこに時間度を取ります。すばらしい。すべてうまく機能しているようです。すべて実行されています。1 つだけ小さなことが起きます。60 秒に達したときに、
09:36~10:26
秒針が12時に達した時の挙動がおかしい件
口頭の説明のみ。
ほぼ 360 度に達したところで、突然 2 度になります。ここからここまでは自動的には変化しません。これが起こるのを待ちましょう。さて、これがもうすぐ終わるのがわかりますか? ああ、奇妙な音がします。何が起こっているかというと、最終的な度数に達したときに、0 度または 90 度に変換されます。そして、前進するのではなく、目的の場所に到達するためにずっと後戻りします。ここでできることは、度数を数えてカウントを続けることです。または、JavaScript を使用して一時的に遷移を解除し、次の度数に達したときに後戻りしないようにすることもできます。その後、再度適用します。これは、set date 内の if ステートメントで実行できます。
今日はここまでです。また明日お会いしましょう。
学んだこと
divに時計らしい動きをさせるためのCSS設定
- Transform Origin(始点):「100%(右端)」※デフォルトは「50%(中心)」
- Transform(変形):rotate(回転)の度数「90deg(90度)」
- Transition(遷移):変形にかける秒数「all 0.5s」
- 3 次ベジェのトランジションタイミング関数(動き方):開発者ツールで編集可能。滑らかにしたり、軽くバウンドさせたりできる
時計のように動かすロジック
- new Date():現在時刻の取得
- .getSeconds():現在時刻の秒数を取得
- .style.transform:JavaScriptでCSSのtransformを変更
const minsHand = document.querySelector('.min-hand'); // 分針の要素を取得
const now = new Date();
const mins = now.getMinutes(); // 現在の分数を取得
const minsDegrees = ((mins / 60) * 360) + 90; // 分数を度数に変換
minHand.style.transform = `rotate({$minDegrees}deg)`; // cssのtransform変更
感想
Redux脳になっていたので、状態を監視するのかな?状態変化を感知して針を動かすのかな?と思ったけど
「毎秒ごとに関数を動かす」というシンプルな考え方だった。