2015年9月27日日曜日

「Javascriptで方向幕再現」の作り方

お久しぶりです、chiko ryoです。

今回は、以前お約束した「209系方向幕をJavaScriptで作る」 の解説です。

では、いきなりですがソースを貼ります。

function myMaku(){
         var Y = eval(document.makuform.zahyo.value);
         if(Y < 0 || Y > 44){            // 44の部分は対応番号が何番まであるかで調整ください。
          alert("0~44までの適正な値を入力してください。");
          return false;
         }
         // 移動先の座標を取得
         Yfor = eval("document.makuform.s" + String(Y) + ".value");
         // スタート地点の座標を取得
         Yfrom = document.getElementById("maku").contentWindow.document.body.scrollTop;
         // 幕を動かすスピードを取得
         Ys = eval(document.makuform.speed.value) / 1000;
         // 上に行くのか下に行くのか?
         if(Yfor < Yfrom){   // Y座標を小さくしていく
          Ys = (-1) * Ys;    // -1を掛けて正負を逆転する
          my_parse = false;
         }else if(Yfor > Yfrom){
          my_parse = true;
         }else{              // 移動は不要
          return false;
         }
         makuI = Yfrom;
         myMakuReturn = setInterval("myMakucore()", 1);
         return false;
         
}

function myMakucore(){
 if(Ys > 0 && makuI > Yfor){   // Y座標が増えていって、オーバーした
  document.getElementById("maku").contentWindow.document.body.scrollTop = Yfor;
  clearInterval(myMakuReturn);
  return;
 }else if(Ys < 0 && makuI < Yfor){ // Y座標が減っていって、オーバーした
  document.getElementById("maku").contentWindow.document.body.scrollTop = Yfor;
  clearInterval(myMakuReturn);
  return;
 }else if(makuI == Yfor){
  clearInterval(myMakuReturn);
  return;
 }else{
  makuI = makuI + Ys;
  document.getElementById("maku").contentWindow.document.body.scrollTop = makuI;
 }
}

<form name="makuform" onSubmit="return myMaku();"><div class="box" id="box">
<iframe src="209gazo.html" id="maku"></iframe>
</div><br>
幕対応番号を入力: 
<input type="text" name="zahyo" value="" /><br />
幕を動かすスピードを選択: 
<input type="range" name="speed" min="1" max="300" step="1" value="150" />
<input type="submit" name="go" value=" 実行 " /></p>
<p>幕対応表<br /><br />
<table border="1">
<tr>
<td>0<input type="hidden" name="s0" value="0" /></td><td>これ以上巻くな</td></tr>
<tr><td>1<input type="hidden" name="s1" value="135" /></td><td>試運転</td></tr>
<tr><td>2<input type="hidden" name="s2" value="280" /></td><td>回送</td></tr>
<tr><td>3<input type="hidden" name="s3" value="435" /></td><td>臨時</td></tr>
<tr><td>4<input type="hidden" name="s4" value="590" /></td><td>京浜東北線</td></tr>
<tr><td>5<input type="hidden" name="s5" value="748" /></td><td>品川</td></tr>
<tr><td>6<input type="hidden" name="s6" value="900" /></td><td>大崎</td></tr>
<tr><td>7<input type="hidden" name="s7" value="1050" /></td><td>田町</td></tr>
<tr><td>8<input type="hidden" name="s8" value="1200" /></td><td>池袋</td></tr>
<tr><td>9<input type="hidden" name="s9" value="1350" /></td><td>山手線</td></tr>
<tr><td>10<input type="hidden" name="s10" value="1500" /></td><td>田端</td></tr>
<tr><td>11<input type="hidden" name="s11" value="1650" /></td><td>上野</td></tr>
<tr><td>12<input type="hidden" name="s12" value="1800" /></td><td>快速上野</td></tr>
<tr><td>13<input type="hidden" name="s13" value="1960" /></td><td>赤羽</td></tr>
<tr><td>14<input type="hidden" name="s14" value="2100" /></td><td>快速赤羽</td></tr>
<tr><td>15<input type="hidden" name="s15" value="2260" /></td><td>大宮</td></tr>
<tr><td>16<input type="hidden" name="s16" value="2410" /></td><td>快速大宮</td></tr>
<tr><td>17<input type="hidden" name="s17" value="2550" /></td><td>蒲田</td></tr>
<tr><td>18<input type="hidden" name="s18" value="2700" /></td><td>快速蒲田</td></tr>
<tr><td>19<input type="hidden" name="s19" value="2850" /></td><td>鶴見</td></tr>
<tr><td>20<input type="hidden" name="s20" value="3000" /></td><td>快速鶴見</td></tr>
<tr><td>21<input type="hidden" name="s21" value="3150" /></td><td>磯子</td></tr>
<tr><td>22<input type="hidden" name="s22" value="3300" /></td><td>快速磯子</td></tr>
<tr><td>23<input type="hidden" name="s23" value="3455" /></td><td>南浦和</td></tr>
<tr><td>24<input type="hidden" name="s24" value="3603" /></td><td>快速南浦和</td></tr>
<tr><td>25<input type="hidden" name="s25" value="3755" /></td><td>東十条</td></tr>
<tr><td>26<input type="hidden" name="s26" value="3903" /></td><td>快速東十条</td></tr>
<tr><td>27<input type="hidden" name="s27" value="4055" /></td><td>桜木町</td></tr>
<tr><td>28<input type="hidden" name="s28" value="4203" /></td><td>快速桜木町</td></tr>
<tr><td>29<input type="hidden" name="s29" value="4370" /></td><td>東神奈川</td></tr>
<tr><td>30<input type="hidden" name="s30" value="4515" /></td><td>快速東神奈川</td></tr>
<tr><td>31<input type="hidden" name="s31" value="4665" /></td><td>大船</td></tr>
<tr><td>32<input type="hidden" name="s32" value="4815" /></td><td>快速大船</td></tr>
<tr><td>33<input type="hidden" name="s33" value="4968" /></td><td>八王子</td></tr>
<tr><td>34<input type="hidden" name="s34" value="5118" /></td><td>快速八王子</td></tr>
<tr><td>35<input type="hidden" name="s35" value="5280" /></td><td>橋本</td></tr>
<tr><td>36<input type="hidden" name="s36" value="5425" /></td><td>快速橋本</td></tr>
<tr><td>37<input type="hidden" name="s37" value="5575" /></td><td>町田</td></tr>
<tr><td>38<input type="hidden" name="s38" value="5723" /></td><td>快速町田</td></tr>
<tr><td>39<input type="hidden" name="s39" value="5870" /></td><td>中山</td></tr>
<tr><td>40<input type="hidden" name="s40" value="6010" /></td><td>快速中山</td></tr>
<tr><td>41<input type="hidden" name="s41" value="6165" /></td><td>小机</td></tr>
<tr><td>42<input type="hidden" name="s42" value="6315" /></td><td>快速小机</td></tr>
<tr><td>43<input type="hidden" name="s43" value="6465" /></td><td>横浜線</td></tr>
<tr><td>44<input type="hidden" name="s44" value="8868" /></td><td>これ以上巻くな</td></tr>
</table>
</form>
</p>

.box{
height: 150px;
width: 400px;
padding: none;
overflow: auto;
border: none;
-webkit-overflow-scrolling: touch;
}

#maku{
display: block;
width: 100%;
height: 100%;
border: none;
}

目がおかしくなった人、ごめんなさい。

では、軽く解説を。まずはmyMaku()からいきます。

var Y = eval(document.makuform.zahyo.value);
Yに幕対応番号を代入しています。eval()に渡しているのは数値に変換するためです。脆弱性とか気にしないww

if(Y < 0 || Y > 44){            // 44の部分は対応番号が何番まであるかで調整ください。
  alert("0~44までの適正な値を入力してください。");
  return false;
}
存在しない番号が入力された際のエラー対策です。

// 移動先の座標を取得
Yfor = eval("document.makuform.s" + String(Y) + ".value");
ここは少し難しいので解説します。
まずeval()の引数からみてみます。
"document.makuform.s" + String(Y) + ".value"
name属性値がmakuformであるform要素を取得しているのはわかりますよね?(そこまでは解説しません)
変数Yには、幕対応番号が数値型で代入されています。(2行目にeval()があります)
それをString()に渡していますので、文字列型に変換されます。
つまり、"s"と幕対応番号を文字列として連結して生成した文字列と同じname属性値を持つinput要素を取得しています。
例えば幕対応番号3の場合、
"document.makuform.s" + String(3) + ".value"
となり、document.makuform.s3.valueという文字列が生成されます。
それをeval()に渡してvalueを取得しているのです。

if(Yfor < Yfrom){   // Y座標を小さくしていく
Ys = (-1) * Ys;    // -1を掛けて正負を逆転する
    my_parse = false;
}else if(Yfor > Yfrom){
    my_parse = true;
}else{              // 移動は不要
    return false;
}
makuI = Yfrom;
myMakuReturn = setInterval("myMakucore()", 1);
return false;
if文で幕が上へ行くべきか下へ行くべきかを判断させます。
現状のscrollTopよりも行先のscrollTopのほうが小さい場合はscrollTopを減らしていく必要があります。
実際にscrollTopの改変をしている41行目では加算をしています。
「ある実数(makuI)にもう一つの実数(Ys)を足すと、元の実数(makuI)が小さくなった」 という動作が要求されますので、Ysを負の数にしましょう。そこで(-1)を掛け算します。
正の数 * 負の数 = 負の数です。正の数 + 負の数 は元の数より小さくなります。

ここで解説は以上です。ここまでついてこられた方であれば難なく理解いただけると思います。

0 件のコメント:

コメントを投稿

質問や意見などどしどしお寄せください!!