From window, to wind

趣味のゲームとJavaプログラムなどについて 適当に書き綴るブログ

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Sidebarで動く砂時計タイマー

Windowsの砂時計のアイコンのデザインを利用した砂時計のタイマーです。
砂時計だけだとわかりづらいので、自前のプログレスバーと経過時間を表示しています。
(4月8日修正)
タイマーの時間経過をカウント数ではなく経過時間に変更。
終了時にVBSでメッセージボックスを表示させるようにしています。
ソースコード
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>SandGlass</title>
<script type="text/javascript">
<!--

var count = 180;
var nowtime = 180;
var dd;
var presec = 0;

function initial(){
System.Gadget.settingsUI = "setting.html";
System.Gadget.onSettingsClosed = closeSetting;
System.Gadget.Settings.write("time",count);
System.Gadget.Settings.write("key",false);
}

function closeSetting(ev){
if(ev.closeAction == ev.Action.commit){
count=System.Gadget.Settings.read("time");
dd = new Date();
presec = dd.getTime();
nowtime = 0;
}
timecount();
}

function load(){
if(System.Gadget.Settings.read("key")){
dd = new Date();
presec = dd.getTime();
nowtime = 0;
}else{
nowtime = 0;
System.Gadget.Settings.write("key",true);
dd = new Date();
presec = dd.getTime();
timecount();
}

}

function timecount(){

if(nowtime*100/count<10){
imgpath = "0%"+(nowtime%2+1);
}else if(nowtime*100/count<20){
imgpath = "10%"+(nowtime%2+1);
}else if(nowtime*100/count<30){
imgpath = "20%"+(nowtime%2+1);
}else if(nowtime*100/count<40){
imgpath = "30%"+(nowtime%2+1);
}else if(nowtime*100/count<50){
imgpath = "40%"+(nowtime%2+1);
}else if(nowtime*100/count<60){
imgpath = "50%"+(nowtime%2+1);
}else if(nowtime*100/count<70){
imgpath = "60%"+(nowtime%2+1);
}else if(nowtime*100/count<80){
imgpath = "70%"+(nowtime%2+1);
}else if(nowtime*100/count<90){
imgpath = "80%"+(nowtime%2+1);
}else if(nowtime*100/count<100){
imgpath = "90%"+(nowtime%2+1);
}else{
imgpath = "100%"+(nowtime%2+1);
}

document.getElementById("sand").src = "./img/"+imgpath+".png";
document.getElementById("bar").style.width = nowtime*100/count;
document.getElementById("time").innerHTML = ""+nowtime+"<hr>"+count;

if(nowtime<count){
if(System.Gadget.Settings.read("key")){
dd = new Date();
nowtime = Math.floor((dd.getTime()-presec)/1000);
setTimeout("timecount()",1000);
}
}else{
System.Gadget.Settings.write("key",false);
document.getElementById("time").innerHTML = "Finish";
var message = ""+count+"秒 経過しました。";
showDialog(message);
}
}
//-->

</script>

<SCRIPT LANGUAGE="VBScript">
<!--
Function showDialog(msg)
Dim ans
ans = MsgBox (msg, 48, "タイマーの終了")
End Function
-->

</SCRIPT>

<style>
.body {
top:0px;
left:0px;
width:130px;
height:80px;
font-size:12pt;
color: "#ffffff";
font-family: Meiryo;
scroll:no;
padding:0px;
margin:0px;
position:absolute;
}
span {
background: transparent url('img/bar.png') repeat-x;
color: #006faf;
display: block;
float: left;
font: bold 12px arial, sans-serif;
position: absolute;
top: 66px;
left: 15px;
height: 14px;
width: 0px;
z-index: 4;
}
div.timeview{
position: absolute;
color: #006faf;
display: block;
float: left;
font: bold 18px Meiryo, sans-serif;
top: 6px;
left: 64px;
height: 64px;
width: 60px;
z-index: 5;
text-align: center;
line-height: 18px;
}
</style>
</head>
<body class="body" onload="initial();">
<g:background id="plate" style="position:absolute;
top:0; left:0; z-index:0;"
src="./img/plate.png" />

<g:image id="bg" onClick="load();" style="position:absolute;
top:2; left:0; z-index:1;"
src="./img/base.png" />

<g:image id="sand" onClick="load();" style="position:absolute;
top:2; left:0; z-index:2;"
src="./img/100%1.png" />

<g:image id="barbg" style="position:absolute;
top:66; left:0; z-index:3;"
src="./img/barbg.png" />

<div class="timeview" id="time">180<hr>180</div>
<span id="bar"></span>
</body>
</html>


解説
砂時計は落ちていく砂の画像ファイルを10%刻みで2種類用意して奇数と偶数で画を変え砂が落ちていく様子を表現しています。砂の量が違うとの突っ込みはでっかい禁止です。プログレスバーは1×14の画像ファイルをcssで横に繰り返し表示させるようにして、barのwidthの値をJavaScript中で制御して進展させています。経過時間の表示は水平線のタグを利用しています。

タイマーの開始にload()メソッドを呼び出し、初期クリック、途中クリック、終了後のクリック、設定ダイアログの終了時によってkeyの値を変えて制御しています。

問題だったのは設定ダイアログを呼び出したあと普通にload()を呼び出していたため、Timecount()が二つ同時に走り倍速で時間が進んでしまいました。同様に途中でクリックするときにも二重でTimecountが呼び出されました。そこで設定ダイアログを呼び出した後は、Timecount()を一度終了させてからloadを呼び出そうと思い、再帰呼び出しのところにif文を加えました。しかしながらこれではクリック時に対応できないため、現在のカウント時間の初期化の所に着目して4種類での場合分けを行いました。
まず初期クリックと終了後のクリックが同じになるようにkeyの値を変え、途中クリックでは経過時間の値だけを変更するようにしました。設定ダイアログは呼び出したときにTimecountが一度終了し、その後loadではなくTimecountを呼び出すことにしました。

この方法だともしかしたら終了時にクリックすると…運が悪いと二重呼び出しするかも知れませんが、その場合は設定ダイアログを呼び出して一度処理を終了させてください。

(4月8日修正)
カウント数nowtimeを経過時間に変更し、開始時の時間msecをgetTime()メソッドで取得し、カウントしていくときの時間との差を秒数に直し、整数に直しています。
また終了時にVisualBasicScriptを用いてMsgBox関数でメッセージボックスを表示させています。
メッセージボックスはJavaScriptにもあるのですが、ガジェットでは使用することができないのでVBSを用いました。
スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

トラックバックURLはこちら
http://kagenyan.blog69.fc2.com/tb.php/38-be12e747
この記事にトラックバックする(FC2ブログユーザー)

FC2Ad

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。