検索
ホームページウェブフロントエンドjsチュートリアルCanvasを使った時計アニメーションの作り方

JavaScriptからCanvasへの知識ポイントを復習して、Canvasを使って描画された静的な時計の例を見て、これをシステム時間を動的に表示する時計アニメーションにしたいと思いました。さらにデジタル表示時計と合わせて小型時計モジュールが誕生!現在のインターフェイスはまだ比較的粗く、シンプルなインターフェイスとアニメーション効果のみが含まれています。

この時計には、アニメーションディスク時計とデジタル時計の 2 つの部分が含まれています。 1 つ目は、タイムアウトを使用して setTimeout() メソッドを呼び出し、時間を表示するループ アニメーション効果を作成する方法です。まずデジタル時計のコードを見てみましょう。ディスク時計もデジタル時計を模倣して作られています。


var ntimeoutId = setTimeout(ntimeOut,0);function ntimeOut() {
    clearTimeout(ntimeoutId);    
    var now = new Date();    
    var hours = now.getHours().toString(),
        minutes = now.getMinutes().toString(),
        seconds = now.getSeconds().toString();    
        var time = hours+" : "+minutes+" : "+seconds;    
        var timep = document.getElementById("time");
    timep.innerHTML = time;
    ntimeoutId = setTimeout(ntimeOut, 1000);
}

1. まず、システムの現在時刻を表示するメソッドを初めて呼び出すタイムアウト呼び出しを設定します。時間を0に設定しているのは、遅延なく時刻を表示するためです。 。

2. 各ループの前に前のタイムアウト呼び出しをクリアします (なぜこれを行うのか、まだわかりません??? メモリのパフォーマンスに関連している可能性があります。コメント後、プログラムは正常に実行できます。)

3. 現在のシステム時刻を取得し、特定の文字列形式で保存します。

4. ページ上に動的に表示するために、HTML ページに時間文字列を格納する空の p 要素を定義します。 DOM 操作を使用して p 要素に追加し、動的に表示します。

5. タイムアウト呼び出しを継続的にループすることで、デジタル時計を動的に表示することができます。また、開発者ツールを通じて p 要素の動的な変化を確認することもできます。

次のステップは、ディスク時計アニメーションを作成することです。ディスクと数値の描写は比較的単純で、context.arc() メソッドと context.fillText() メソッドを使用するだけです。以下はそのソースコードです:


     context.beginPath();
        context.restore();
        context.translate(0,0);
        context.clearRect(0,0,300,300);        //绘制时钟内外边框
        context.arc(150,150,149,0,2 * Math.PI,false);
        context.moveTo(295,150);
        context.arc(150,150,145,0,2 * Math.PI,false);

        context.font = "bold 18px Arial";
        context.textAlign = "center";        //绘制时钟表盘数值
        context.fillText("12",150,25);
        context.fillText("3",285,150);
        context.fillText("6",150,290);
        context.fillText("9",15,150);
        context.fillText("1",215,45);
        context.fillText("2",265,95);
        context.fillText("4",265,225);
        context.fillText("7",95,275);
        context.fillText("5",215,275);
        context.fillText("8",35,225);
        context.fillText("10",35,95);
        context.fillText("11",75,45);

        context.stroke();
        context.closePath();

次のステップはポインタを描画することです。ポインタを描画する際には、立面図のメソッドを参照して、変換操作 context.translate() メソッドを使用します。原点を選択してから、ポインタとなるパスを描画する方が便利です。ポインタを描画する際のもう 1 つの困難は、ラジアンの計算です。もちろん、これは数学的な問題です。まずソース コードを見てみましょう:


     //绘制指针        context.save();
        context.translate(150,150);        //时针
        context.moveTo(0,0);
        hour(hours);        function hour(thour) {
            context.save();            
            var newhour = 0;            
            if(thour>12) {
                newhour = thour-12;
            } else {
                newhour = thour;
            }
            context.rotate((2*Math.PI/12)*newhour);
            context.lineTo(0,-80);
            context.restore();
        }        //分针
        context.moveTo(0,0);
        minute(minutes);        function minute(tminute) {
            context.save();
            context.rotate((2*Math.PI/12)*tminute/5);
            context.lineTo(0,-110);
            context.restore();
        }        //秒针
        context.moveTo(0,0);
        second(seconds);        function second(tsecond) {
            context.save();
            context.fillStyle = "#fff";
            context.rotate((2*Math.PI/12)*tsecond/5);
            context.lineTo(0,-120);
            context.restore();
        }
        
        context.stroke();

ポインターを描画する場合、各タイプのポインターは関数を使用して各ポインター描画の円弧を変更し、ポインター回転のアニメーション効果を実現します。短針は、24 時間時計を 12 時間時計に変換し、毎回 30 度回転させます。長針と秒針は 0 から 11 まで回転します。簡単な数学の問題は、私よりも皆さんのほうが得意だと思います。私はまだしばらく苦労していました。 context.save() メソッドと context.restore() メソッドは、初期化中にパスを保存および復元するために各関数で使用されます。そうしないと、ポインターが軌道から外れてしまいます。

次に、タイムアウト呼び出しに時計のダイヤルとポインターを配置するだけで、すべての作業が完了します。ただし、原点の設定など、注意する必要がある問題がまだいくつかあります。時計の文字盤と針は異なります。保存と復元を使用して初期化パスを復元しないと、時計の文字盤と針が軌道から外れてしまいます。もう 1 つ注意すべき点は、Canvas を使用してアニメーションを作成する場合、各アニメーション サイクルで Canvas をクリアして再描画する必要があることです。そうしないと、ポインタが回転し続けて花になってしまいます。

完全なディスク クロック コードは次のとおりです:


//显示指针时间var drawing = document.getElementById("drawing");if(drawing.getContext) {    
var context = drawing.getContext("2d");    
var rtimeoutId = setTimeout(roudClock,0);    
function roudClock() {
        clearTimeout(rtimeoutId);

        context.beginPath();
        context.restore();
        context.translate(0,0);
        context.clearRect(0,0,300,300);        //绘制时钟内外边框
                context.arc(150,150,149,0,2 * Math.PI,false);
        context.moveTo(295,150);
        context.arc(150,150,145,0,2 * Math.PI,false);

        context.font = "bold 18px Arial";
        context.textAlign = "center";        //绘制时钟表盘数值
                context.fillText("12",150,25);
        context.fillText("3",285,150);
        context.fillText("6",150,290);
        context.fillText("9",15,150);
        context.fillText("1",215,45);
        context.fillText("2",265,95);
        context.fillText("4",265,225);
        context.fillText("7",95,275);
        context.fillText("5",215,275);
        context.fillText("8",35,225);
        context.fillText("10",35,95);
        context.fillText("11",75,45);

        context.stroke();
        context.closePath();        
        var now = new Date();        
        var hours = now.getHours(),
            minutes = now.getMinutes(),
            seconds = now.getSeconds();        //绘制指针        
            context.save();
        context.translate(150,150);        //时针
                context.moveTo(0,0);
        hour(hours);        
        function hour(thour) {
            context.save();            
            var newhour = 0;            
            if(thour>12) {
                newhour = thour-12;
            } else {
                newhour = thour;
            }
            context.rotate((2*Math.PI/12)*newhour);
                        context.lineTo(0,-80);
            context.restore();
        }        //分针
           context.moveTo(0,0);
        minute(minutes);        
        function minute(tminute) {
            context.save();
            context.rotate((2*Math.PI/12)*tminute/5);
            context.lineTo(0,-110);
            context.restore();
        }        //秒针
                context.moveTo(0,0);
        second(seconds);        
        function second(tsecond) {
            context.save();
            context.fillStyle = "#fff";
            context.rotate((2*Math.PI/12)*tsecond/5);
            context.lineTo(0,-120);
            context.restore();
        }
        
        context.stroke();
        context.restore();
        context.translate(0,0);
        context.save();
        rtimeoutId = setTimeout(roudClock,1000);
    }    
}

最後に、このデモ演習中に遭遇した問題をまとめます:

1. キャンバスの再描画の問題

ポインター アニメーションがループすると、前のパスをクリアする方法がなくなり、各ループに跡が残ります。狭い範囲でclearRect()メソッドを使用してみましたが、範囲内のダイヤルと数字の内容しかクリアできず、ポインタの痕跡が残ることがわかりました。その後、検索して得た答えは、Canvas を使用してアニメーションを作成する場合は、新しいコンテンツを描画する前にキャンバスのコンテンツをクリアする必要があり、アニメーションの変更はすべてクリアする必要があるということでした。再描画方法についてはリンクを参照してください。clearRect()メソッドを使用してキャンバス全体をクリアします。

2. save()メソッドとrestore()メソッドの使用

時計の文字盤とポインターの原点設定が異なるため、再描画後は時計の文字盤の原点がポインターなので、save() メソッドとrestore() メソッドを使用して変更します。この場所以外にも使用する必要がある場所があり、操作後に設定を変更したが、その後の操作では元の設定を使用する必要がある場合に適しています。これら 2 つの方法では、設定の保存と復元のみが行われ、コンテンツは保存されないことに注意してください。

3.translate()メソッドの使用

translate()メソッドは変形操作に属し、キャンバスの原点を変更できます。キャンバスのデフォルトの原点はキャンバスの左上隅にあります。 。このメソッドを使用すると、ポインタのパスを描画しやすくなります。もちろん、まだ触れていない他の用途もあります。

4. setTimeout()メソッドの使用

タイムアウト呼び出しを使用することは、断続的な呼び出しをシミュレートすることができるより良い方法です。タイムアウト呼び出しが渡される関数内にタイムアウト呼び出しを追加すると、ループを適切にシミュレートできます。関数内のいくつかの条件に基づいてループの数と時間を制限することもできます。

5. 現在の時刻に対応する、ラジアンの使い方

これは数学の問題で、ずっと角を曲がらずに悩んでいましたが、原理がわかれば問題ありません。技術的な問題。

6. timeメソッドの繰り返し取得と再利用の問題について

コード内に重複コードが存在する状況に関しては、冗長性を減らすためのこれより良い方法は思いつきませんでした。たとえば、取得時間に関しては、2 つのタイムアウト呼び出しに繰り返し定義がありますが、それらがグローバルに配置されている場合、アニメーション効果はなく、読み込みが完了した後の静的な時間のみが表示されます。もう一つは、ポインタの関数設定に繰り返し部分があるのですが、それを一つの関数メソッドにまとめて呼び出すことはできるのでしょうか?

誰もがアイデアを出したり、欠点を補ったり、一緒にコミュニケーションしたりすることを歓迎します。

以上がCanvasを使った時計アニメーションの作り方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
JavaScriptの起源:その実装言語の調査JavaScriptの起源:その実装言語の調査Apr 29, 2025 am 12:51 AM

JavaScriptは1995年に発信され、Brandon Ikeによって作成され、言語をCに実現しました。 2。JavaScriptのメモリ管理とパフォーマンスの最適化は、C言語に依存しています。 3. C言語のクロスプラットフォーム機能は、さまざまなオペレーティングシステムでJavaScriptを効率的に実行するのに役立ちます。

舞台裏:JavaScriptをパワーする言語は何ですか?舞台裏:JavaScriptをパワーする言語は何ですか?Apr 28, 2025 am 12:01 AM

JavaScriptはブラウザとnode.js環境で実行され、JavaScriptエンジンに依存してコードを解析および実行します。 1)解析段階で抽象的構文ツリー(AST)を生成します。 2)ASTをコンパイル段階のバイトコードまたはマシンコードに変換します。 3)実行段階でコンパイルされたコードを実行します。

PythonとJavaScriptの未来:傾向と予測PythonとJavaScriptの未来:傾向と予測Apr 27, 2025 am 12:21 AM

PythonとJavaScriptの将来の傾向には、1。Pythonが科学コンピューティングの分野での位置を統合し、AI、2。JavaScriptはWebテクノロジーの開発を促進します。どちらもそれぞれのフィールドでアプリケーションシナリオを拡大し続け、パフォーマンスをより多くのブレークスルーを行います。

Python vs. JavaScript:開発環境とツールPython vs. JavaScript:開発環境とツールApr 26, 2025 am 12:09 AM

開発環境におけるPythonとJavaScriptの両方の選択が重要です。 1)Pythonの開発環境には、Pycharm、Jupyternotebook、Anacondaが含まれます。これらは、データサイエンスと迅速なプロトタイピングに適しています。 2)JavaScriptの開発環境には、フロントエンドおよびバックエンド開発に適したnode.js、vscode、およびwebpackが含まれます。プロジェクトのニーズに応じて適切なツールを選択すると、開発効率とプロジェクトの成功率が向上する可能性があります。

JavaScriptはCで書かれていますか?証拠を調べるJavaScriptはCで書かれていますか?証拠を調べるApr 25, 2025 am 12:15 AM

はい、JavaScriptのエンジンコアはCで記述されています。1)C言語は、JavaScriptエンジンの開発に適した効率的なパフォーマンスと基礎となる制御を提供します。 2)V8エンジンを例にとると、そのコアはCで記述され、Cの効率とオブジェクト指向の特性を組み合わせて書かれています。3)JavaScriptエンジンの作業原理には、解析、コンパイル、実行が含まれ、C言語はこれらのプロセスで重要な役割を果たします。

JavaScriptの役割:WebをインタラクティブでダイナミックにするJavaScriptの役割:WebをインタラクティブでダイナミックにするApr 24, 2025 am 12:12 AM

JavaScriptは、Webページのインタラクティブ性とダイナミズムを向上させるため、現代のWebサイトの中心にあります。 1)ページを更新せずにコンテンツを変更できます。2)Domapiを介してWebページを操作する、3)アニメーションやドラッグアンドドロップなどの複雑なインタラクティブ効果、4)ユーザーエクスペリエンスを改善するためのパフォーマンスとベストプラクティスを最適化します。

CおよびJavaScript:接続が説明しましたCおよびJavaScript:接続が説明しましたApr 23, 2025 am 12:07 AM

CおよびJavaScriptは、WebAssemblyを介して相互運用性を実現します。 1)CコードはWebAssemblyモジュールにコンパイルされ、JavaScript環境に導入され、コンピューティングパワーが強化されます。 2)ゲーム開発では、Cは物理エンジンとグラフィックスレンダリングを処理し、JavaScriptはゲームロジックとユーザーインターフェイスを担当します。

Webサイトからアプリまで:JavaScriptの多様なアプリケーションWebサイトからアプリまで:JavaScriptの多様なアプリケーションApr 22, 2025 am 12:02 AM

JavaScriptは、Webサイト、モバイルアプリケーション、デスクトップアプリケーション、サーバー側のプログラミングで広く使用されています。 1)Webサイト開発では、JavaScriptはHTMLおよびCSSと一緒にDOMを運用して、JQueryやReactなどのフレームワークをサポートします。 2)ReactNativeおよびIonicを通じて、JavaScriptはクロスプラットフォームモバイルアプリケーションを開発するために使用されます。 3)電子フレームワークにより、JavaScriptはデスクトップアプリケーションを構築できます。 4)node.jsを使用すると、JavaScriptがサーバー側で実行され、高い並行リクエストをサポートします。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター