アナログ時計に目盛りを追加しよう
前回は長針、短針、秒針のみを表示するアナログ時計を作成しました。
今回は前回のアナログ時計の盤面に、目盛りを付けてみましょう。
目盛りの付け方
目盛りは1分単位(6度間隔)として、全部で60個表示します。
ただし、正時(1時、2時のように端数のない時刻)は、目盛りを太く長くして他の目盛りより目立つようにします。
正時は30度単位なので、角度が30で割り切れる時に目盛りを太く長くします。
アナログ時計に目盛りを表示するプログラム
アナログ時計に目盛りを表示するプログラムは、以下のようになります。
38行目のfor文は、0、6、12 ... 354を変数angleに代入していきます。
変数angleは三角関数で使う角度です。
40行目のif文は、30で割った時に余りが0かどうかを判定し、余りが0の時は目盛りを太く長くします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Clock</title> </head> <body onload="strClock();"> <canvas id="pos" width="400" height="400"></canvas> <script type="text/javascript"> // 定数 const CEN_X = 200; const CEN_Y = 200; const SEMICIRCLE = 180; // 針表示関数 function needle(fig) { // 現在時刻を取得 var now = new Date(); // 各針の角度を計算 var angle_h = Math.round(90 - 30 * now.getHours() - 0.5 * now.getMinutes()); // 短針 var angle_m = Math.round(90 - 6 * now.getMinutes()); // 長針 var angle_s = Math.round(90 - 6 * now.getSeconds()); // 秒針 // 円周側の座標を取得 var pos_hx = Math.cos(angle_h*(Math.PI/SEMICIRCLE))*120; var pos_hy = Math.sin(angle_h*(Math.PI/SEMICIRCLE))*120; var pos_mx = Math.cos(angle_m*(Math.PI/SEMICIRCLE))*160; var pos_my = Math.sin(angle_m*(Math.PI/SEMICIRCLE))*160; var pos_sx = Math.cos(angle_s*(Math.PI/SEMICIRCLE))*150; var pos_sy = Math.sin(angle_s*(Math.PI/SEMICIRCLE))*150; line(fig,pos_hx,pos_hy,12,"red"); line(fig,pos_mx,pos_my, 8,"green"); line(fig,pos_sx,pos_sy, 3,"blue"); } // 目盛り表示関数 function memory(fig) { for (angle=0; angle < 360; angle+=6) { // 正時 if (angle % 30 == 0) { fig.lineWidth = 5; var mark_i_x = Math.cos(angle*(Math.PI/SEMICIRCLE))*160; var mark_i_y = Math.sin(angle*(Math.PI/SEMICIRCLE))*160; } // 正時以外 else { fig.lineWidth = 2; var mark_i_x = Math.cos(angle*(Math.PI/SEMICIRCLE))*170; var mark_i_y = Math.sin(angle*(Math.PI/SEMICIRCLE))*170; } var mark_o_x = Math.cos(angle*(Math.PI/SEMICIRCLE))*180; var mark_o_y = Math.sin(angle*(Math.PI/SEMICIRCLE))*180; fig.beginPath(); // 新しいパスを作成 fig.moveTo(CEN_X+mark_i_x,CEN_Y-mark_i_y); // 線の開始座標 fig.lineTo(CEN_X+mark_o_x,CEN_Y-mark_o_y); // 線の終了座標 fig.stroke(); // 線を描画 } } // 直線表示関数 function line(fig,pos_x,pos_y,thick,color) { fig.beginPath(); // 新しいパスを作成 fig.lineWidth = thick; // 線の太さ fig.strokeStyle = color; // 線の色 fig.moveTo(CEN_X,CEN_Y); // 線の開始座標 fig.lineTo(CEN_X+pos_x,CEN_Y-pos_y); // 線の終了座標 fig.stroke(); // 線を描画 } // 円表示関数 function circle(fig,mode,color,thick) { fig.beginPath(); // 新しいパスを作成 fig.arc(CEN_X,CEN_Y,180,0,Math.PI*2); // 円を描画 fig.closePath(); // パスの終了 // 塗りつぶし if (mode == "fill") { fig.fillStyle = color; // 塗りつぶす色 fig.fill(); // 輪郭描画 } else if (mode == "stroke") { fig.strokeStyle = color; // 線の色 fig.lineWidth = thick; // 線の太さ fig.stroke(); } } // 描画開始関数 function strDraw() { // ドキュメントオブジェクト作成 var id1 = document.getElementById('pos'); // 2Dオブジェクト作成 var fig = id1.getContext('2d'); // 画面初期化 fig.clearRect(0,0,400,400); // 円の輪郭描画 circle(fig,"stroke","gold",10); // 円の塗りつぶし circle(fig,"fill", "lightyellow"); // 目盛り描画 memory(fig); // 針描画 needle(fig); } // 開始関数 function strClock() { setInterval("strDraw();",100); } </script> </body> </html> |
ファイルをダブルクリックするとプログラムが実行され、WEBブラウザ上にアナログ時計が表示されます。
JavaScriptの詳しい使い方は、以下の「MDN Web Docs」を参照してください。