ここで何が間違っていますか?
こんにちは、最近、Web Standardsの新しい問題を聞きました。記事「変数の時間」について議論した瞬間、著者はCSS変数を試し、それらに基づいてアナログ時計を作成することにしました。 すべてがゴージャスに見え、最も重要なのは機能しますが、多くの質問があり、少し実験して、同時に私の結論についてお話しすることにしました。
間違ったことは何もありません。CSS変数とCSSのすべてが大好きですが、いつものようにいくつかの欠点があります。 まず、私は個人的には毎秒DOMに書き込むという考えが好きではありません。DOMに関連するものはすべてリソースを大量に消費するためです。 第二に、CSS変数は非常に使いやすいという事実にもかかわらず、変数を変更するたびに、それを使用する各要素を再描画するため、賢明に使用する必要があります。 そして、ここで私は自分自身の主な問題を見ます。
Chromeコンソールの[レンダリング]タブは、再描画の確認に役立ちました。
1秒ごとに再描画が行われ、平均fpsが50フレームであり、これはクロックが1つしかないページにあります。
他にどのようにできますか?
そのため、ページを再描画しないアナログ時計を作成し、矢印の位置を計算するためにJavaScriptに依存するタスクを自分で設定しました。 ブラウザのフレームレートにまったく影響を与えないクロック。 私が知っているすべてのCSSプロパティの中で、再描画せずに要素を変換できるのは1つだけです-変換。 それを使用します。
ただし、最初に独自の時計を作成します。これにより、transformプロパティのみで手を動かすのに便利です。 すべての矢印を使用してダイヤルを作成します。
ここでのアイデアは次のとおりです。各矢印を時計の中心にある別のコンテナに配置し、このコンテナを中心に対して回転させると、矢印自体が回転します。 このようなコンテナの時計回りのスタイルの例を次に示します。
.clock__hand { margin-left: -0.5em; margin-top: -0.5em; font-size: inherit; position: absolute; display: block; height: 1em; width: 1em; left: 50%; top: 50%; } .clock__hand--hour::after { content: ""; border-radius: 0.015em 0.015em 0.01em 0.01em; background-color: #000; margin-bottom: -0.02em; margin-left: -0.025em; font-size: inherit; position: absolute; display: block; height: 0.25em; width: 0.05em; bottom: 50%; left: 50%; }
この場合、font-sizeを使用して、ダイヤルのサイズと時計のすべてのコンポーネントを設定します。
時計自体のタイプコード
さて、どれくらい回転させますか?
矢印を360度回転します。 正しい質問は、どのくらい回転するのかということです。 そして、どの矢印を回転させるかによります。 毎時-12時間、分-時間、秒-分。
.clock__hand--hour { animation: clock-hand-rotate 43200s linear infinite; } .clock__hand--minute { animation: clock-hand-rotate 3600s linear infinite; } .clock__hand--second { animation: clock-hand-rotate 60s linear infinite; } @keyframes clock-hand-rotate { from { transform: rotate(0deg) } to { transform: rotate(360deg) } }
そして、私たちの時計は機能しました。
しかし、Chromeはそれらについて何を教えてくれますか?
再描画なしで安定した60 fps
しかし、これは私たちの時代ではありません。
したがって、すべての矢印が0度からアニメーションを開始するため、最初の時間は00:00:00です。 現在から始めるには、時間に対する各矢印の初期度合いを個別に計算する必要があります。 したがって、2つのオプションがあります。サーバー側で、リクエスト時間に関連してCSSをレンダリングするか、JavaScriptを使用します。 もちろん、スクリプトクロックを使用しないサーバーレンダリングはクールですが、概念を確認するために、JavaScriptを使用しています。
var date = new Date(), hours = date.getHours(), minutes = date.getMinutes(), seconds = date.getSeconds(); if (hours > 12) { hours -= 12; } var secondsStartDegree = 360 / 60 * seconds, minutesStartDegree = 360 / 60 * minutes + 6 / 60 * seconds, hoursStartDegree = 360 / 12 * hours + 30 / 60 * minutes + 0.5 / 60 * seconds; var style = document.createElement('style'); style.type = 'text/css'; style.innerHTML = '\ @keyframes clock-hand-rotate--hour {\ from {transform: rotate(' + hoursStartDegree + 'deg)}\ to {transform: rotate(' + (hoursStartDegree + 360) + 'deg)}\ }\ @keyframes clock-hand-rotate--minute {\ from {transform: rotate(' + minutesStartDegree + 'deg)}\ to {transform: rotate(' + (minutesStartDegree + 360) + 'deg)}\ }\ @keyframes clock-hand-rotate--second {\ from {transform: rotate(' + secondsStartDegree + 'deg)}\ to {transform: rotate(' + (secondsStartDegree + 360) + 'deg)}\ }\ .clock__hand--hour {\ animation: clock-hand-rotate--hour 43200s linear infinite;\ }\ .clock__hand--minute {\ animation: clock-hand-rotate--minute 3600s linear infinite;\ }\ .clock__hand--second {\ animation: clock-hand-rotate--second 60s steps(60) infinite;\ }'; document.getElementsByTagName('head')[0].appendChild(style);
そして、各矢印に対して3つのアニメーションを作成し、それらを対応するクラスに接続します。
結果は次のとおりです。
他に何ができますか?
ブラウザーのリソースをほとんど必要としない時計を持っているという事実を見逃した場合は。 次に、さらにいくつかのチップを示します。
- ジャンプする分針と秒針付きの時計
- 異なるタイムゾーンの時計
- すべてがInternet Explorer 11およびモバイルブラウザーでも機能します。
さて、欠点は何ですか
それほど多くはありませんが、次のとおりです。
- クロックはCSSを使用して時間をカウントするため、重いタスクでスレッドをハンマーで打つと、クロックの実行が停止し、ページが解放されると遅れます。 ただし、これらはすべてキーフレームを再設定することで修正できます。
- たとえば、同じIE11でサイトが完璧に見えるわけではありませんが、一部のセンターは少し偏っています。
まとめ
本番環境でこの時計を使用する方法はわかりませんが、私は個人的に新しいテクノロジーに関して結論を出しました。
そして、古いものがまだたくさんあるのであれば、新しい技術を急いで買う価値があるとは限りません。 そして最も重要なことは、言語の新しい信じられないほどの機能をどこにでも付けようとするよりも、信頼できるツールを上手に使用する方が良いということです。
また、ブラウザのリソースの観点から、単純な描画がこれほど多くのフレームを必要とすることは考えていませんでした。
お読みいただきありがとうございます。