K3の住民

最近レア社のことをほとんど書いていない自称レア社好きがゲームやプログラミングについて色々書いていく。

SDK2時計を作ってみた

皆さん、お久しぶりです。雪圀です。

・・・さて、ブログの「ただいまの時間」(PCのみ)に何か変化があったことに
お気づきでしょうか。
昨日から時計をリニューアルしました。前は質素なものでしたが、今回はデジタル
時計を作ろうと思い、ただ7セグ表記であるだけなのも面白くなかったので少し
変わったデジタル時計を作ろうということで「SDK2時計」を作ってみました。

作った経緯というか

アナログの方が作り甲斐はあるかもしれませんが、正直見栄えが無かったので
デジタルにしてみました。
まぁ、今後変わったアナログ時計を作るかもしれませんが、今のところその予定は
ありません。

デジタルで作るにしてもどうしようかなーってときに、偶然暇つぶしに3DSをやって
いてメニュー画面でVC版「スーパードンキーコング2 ディクシー&ディディー」に
カーソルを合わせたときに思い付きました。

言語は何を使ったの?

HTML5Canvasというものがあり、それをJavaScriptで操作しています。
よって、使っている言語は何と聞かれると、HTML5JavaScriptということになり
ます。

Canvasの基本的な使い方

先ず初めに注意しとかないといけないのが、CanvasIE9以前では使えないということ
ですね。IE9以前でCanvasを使う為にはExplorerCanvasが必要ですが、色々な理由で
敢えて使わないようにしています。

HTML4.01では使えませんので、書式をHTML5にします。その為に最初に以下のタグを
記述します。

<!DOCTYPE html>

後は通常通りHTMLの記述を行い、bodyにcanvasタグを入れることで、Canvasが使用
出来ます。
canvasタグにはサイズを指定する為の属性とJavaScriptで使えるようにするための属性
があるので、それも書きます。

	<body>
		<canvas width="(幅)" height="(高さ)" id="(ID)">
			Canvasが動作できるブラウザが必要です。
		</canvas>
	</body>

次にJavaScriptcanvasタグの内容を変更する為の変数と2Dコンテキストを使う為の
変数を用意すると、CanvasJavaScriptで操作出来るようになります。

var canvas = document.getElementById('(ID)');
var ctxt = canvas.getContext('2d');

画像を扱う際の注意点

Canvasは図形の描画をする為には何も必要ないのですが、画像の描画をする為には
工夫が必要です。

先ずはCanvasで描画をしている部分を関数化し、ページ、画像のロード終了後に
処理を実行させるようにする必要があります。

// ページロード後に処理を実行
window.onload = function() {
	draw();
};

function draw() {
	// Canvasを操作する為の記述
	var canvas = document.getElementById('(ID)');
	var ctxt = canvas.getContext('2d');
	
	// 画像オブジェクト
	var img = new Image();
	img.src = "(画像URL)";
	
	// 画像ロード後に処理を実行
	img.onload = function() {
		ctxt.drawImage( ... );
	};
}

複数の画像を扱う為にも一工夫必要ですが、僕は無駄を省きたかったので、ある方法
を使いました。

画像の一部分だけを描画

Canvasには、画像の一部分だけを描画する方法があります。それには、画像を描画
するメソッドdrawImage()はオーバーロードされていることを知る必要があります。
それを考慮して、以下のリファレンスをご覧ください。

www.html5.jp

一番最後に書かれているメソッドが、画像の一部分を描画するメソッドです。

注意しなければならないのは、横幅dw、縦幅dhはちゃんと切り取った一部分のサイズ
にしなければならないということです。
あとは読んだ通りに記述していけばなんとかなるかと思います。

因みに今回使った画像は以下の画像となります。

f:id:ryoryoau24:20190409101122p:plain
今回使った画像

背景が透明の画像を作ったことがある人なら知っていると思いますが、当然透過処理
は済ませて使っています。

現在時刻の取得

現在時刻を取得するには、以下のように記述します。

var clock = new Date();

年・月・日・時・分・秒はそれぞれで取得する必要があります。

var year = clock.getFullYear();	// 年
var month = clock.getMonth()+1;	// 月
var date = clock.getDate();	// 日
var hour = clock.getHour();	// 時
var min = clock.getMinutes();	// 分
var sec = clock.getSeconds();	// 秒

後は、これらを文字列として格納していくだけです。

var msg = year + "/" + month + "/" + date + /* 省略 */ + sec;

1分のときに01分とかになっていたと思いますが、これにも一工夫必要です。が、これ
に関してはもし作ってみたい場合は自分で調べてください。すいません。

時計として動かす

では、最後についに時計として動かしてみましょう。

その方法としてsetTimeout()関数を使用する方法があります。先ずはとりあえず記述
してみます。

setTimeout(draw, 1000 - time.getUTCMilliseconds());

setTimeout()は1度しか実行されないので、繰り返し実行するならsetInterval()だろ?
と思われた方に書いておきますが、setInterval()よりかはsetTimeout()を使った方が
良い場合があります。
setInterval()は処理開始時に一定時間経過後に実行され、setTimeout()は処理終了時
に一定時間経過後に実行されます。
詳細は省きますが、setTimeout()の方が安定して動作しますので、正確な時計を
作りたいのならsetTimeout()を繰り返し使うという方法を取った方が良いでしょう。
繰り返し使うには、関数の中にsetTimeoutを入れ、関数を呼び出すようにします。

function draw() {
	/* 色々な処理 */
	
	// 時計が1秒経過するごとに実行
	setTimeout(draw, 1000 - time.getUTCMilliseconds());
}

setTimeout()の第二引数はミリ秒単位なので、1000を入れれば良いのでは?と思われる
かもしれませんが、そのままだと処理時間の関係上時刻がずれてしまいます。その
場合、1000ミリ秒から現在のミリ秒数を引くことでずれが解消されます。

それでもこのブログでは・・・

このブログがクッソ重いせいかそのままJavaScriptを読み込むだけでは動きません
でした(おそらく高スぺなら動くかもしれませんが)。ここが時間をかけた要因
です。
色々試行錯誤した結果、結局このブログではSDK2時計は動かないと判断しました。

では、どうやって動かしたのか?というと、iframeタグを使って別のサーバに置いて
いるページを埋め込みました。
つまり、ブログ内で別のページを埋め込むことで対処しました。僕が前に作った
ダウンロードページと全く同じやり方です・・・。

実を言うとこれだけはしたくなかったのですが・・・ブログが重い故仕方無いです。


以上です。ブログ、なんとかして軽くしないとなぁ・・・。
まぁ色々心当たりはあるので、徐々に直していこうとは思っています。

今回はこれくらいにしときます。