「技術メモ」カテゴリーアーカイブ

外部ライブラリを自作して使う

面倒くさい関数は外部ライブラリ化してシンプルにします.

tora.jsという外部ライブラリ(ファイル名はかならずtora.jsに)

function neko(){
var cat = 300;//変数catに300を入れる
return cat;//変数catを返す(返事するってこと)
}

このライブラリは次のhtmlから呼び出します

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="tora.js"></script>
<!-- ここで外部のJavaScriptライブラリを読み込む-->

<title>外部ライブラリの使い方</title>
<meta charset="UTF-8">
</head>
<body>

<div id="hyouji"></div>
<!--idを探させる場合,探す前にそのID付きのタグを書いておくこと(この場合,下のdocumen.getElementの前ってこと)-->


<script type="text/javascript">
var uma = neko();//JavaScriptライブラリを読み込んでおけば,関数(function neko())をいきなり呼び出せる.その結果を変数umaに入れる
document.getElementById("hyouji").innerHTML = uma;//ID hyoujiのあるタグを探して,umaを代入せよ.
</script>


</body>
</html>

tora.jsとこのhtmlファイルは同じ階層に置いてください.

tora.jsで変数に入れた300がhtmlから読み込めていますね.

面倒な処理は外部ライブラリ化すると,htmlの記述も減ってすっきりしますよ〜(整理にもなり,バグの場所も分かりやすくなります)

バスアプリの処理フロー

バスアプリのワークフローです。
他の時刻表の表示にも応用可能ですよ〜

1)日付けを取得
2)日付けリストに日付けを渡して、運行スケジュールを取得
3)運行スケジュールに時刻を渡して次のバス時刻を取得
4)現在の時刻が終バスを越えていたら、終了表示
5)運行時間中であれば、残時間を計算
6)残時間を表示
7)1秒おきに再計算

日付けは、全て1月1日を起点に何日目がどのダイヤか検索しています。
ダイヤは全てで6種類あります。

ダイヤは午前0時を起点として、何分かで検索しています。
午前8時は480分という具合に。

この数字はエクセルなどで一気に計算できます。これをテキストツールでカンマで区切り、配列として組み込んでいます。

今後のレクチャー予定
1)エクセルで時刻リスト
2)検索置換
3)配列の基本
4)配列の検索
5)cssでレイアウト

など
iPhone でも動作しています。

IMG_6929.PNG

バスのWebアプリ

ということで,バスのWEBアプリが一通りできました.

ソースは公開しません〜(関連するテクニックは順次公開)

とりあえず、自力で作ってみてください.

画像は使わずCSSでレイアウトしています

bus

HTML5とjavaScriptで作成していますので,このままスマホアプリも作成できます.(最近のスマホアプリはHTML5で開発できるようになっています)

コピペ5分ほどでAndroidで実行可能に,,,(ビルドにはMonacaを使っています)

もう3分ほどで.apk(Androidのアプリファイル)もビルドできました.

android

この程度であれば,開発コストはHTML5の方が安いかもです.

document.getElementByIdでnullのエラー

3日いろいろなサイトをあたってようやく解決.

現象:document.getElementById(“dia”).innerHTML = hoge;

で,JavaScriptの書き方で反映されないときがある.

自分用時刻表アプリを書いています.出発までの残時間はリアルタイムで反映され便利です.問題は,終バスが出た後のに「本日終了〜」みたいな文字を入れたいのですが,それが表示されずエラーが出ます.

出るエラーは

TypeError: document.getElementById(…) is null

で,この意味はどうやら

「おまえ,そんなID無いよボケ!!」

みたい.

でもHTML上にはちゃんと,

<div.time id=”dia”><p>aaa</p></div>

があります.

で,3日間いろいろなサイトを当たりましたが,どうも実行順の問題のようです.

HTML書類は行の上から実行されますが,HTMLの最後に書かれている<DIV>タグを読み込む前にID検索しようとして,無いと言われるみたい.

解決方法は,HTML全部読み込んだ後にID検索すればいいじゃん!ってことなんですが,ここにも罠が.

</script>の直前にgetDocument~が入っているfucnctionのshowTime()を実行させようと,

window.onload=showTime();

と書いてもエラーが.

何でも,この場合は

window.onload=showTime;

()無しで実行するらしい.

はぁ〜?何でしょこれ?

()をつけると関数を実行,()をつけないと関数を参照という意味らしいですが,,見に行くって,,ねぇ

でもこれでうまく行きそう.

 

平日か土日かを判定させる(時刻表用)

バスの時刻を表示させる場合は,今日のダイヤが何かを判定する必要があります.

ダイヤは5種あります

  • Aダイヤ(平日,講義日)
  • Bダイヤ(平日の集中講義や補講日)
  • Cダイヤ(土曜日)
  • 臨時(定期試験,入試,学祭など)
  • 運休日(日曜,祝日,大学の休みの日)

そのプログラムを考え,どのタイミングで判定させると効率が良いか考えてみましょう.例えば先に土日の判定をするとそこで別の処理へ行き,臨時ダイヤの土曜日のif文までたどりつけない可能性があります.

一般の電車の時刻表などは,元旦と祝日が例外日で,後は平日か土日かの処理です.ただし運行会社によっては,土曜と日曜のダイヤが異なることもあるようですので注意してください.

<!DOCTYPE html>
<html>
<head>
<title>Byou</title>
<meta charset="UTF-8">
</head>
<body>
<h1>Byou</h1>


<script type="text/javascript">
setInterval(myYoubi, 100);//myByouってfucitonを100ミリ秒おきに実行してね
var kyouYoubi;
//----曜日だけとるなら100ミリごとにやらなくてもいいですが,,

function myYoubi() {
myDate = new Date();//日付をとってきてmyDateにいれる.このfunctionの外に書くと1回しか日付をとってこないので,秒が更新されない
myYou = myDate.getDay();//myDateの中から曜日だけとりだす.getDay()がその機能.0が日曜,6が土曜日/ちな,日付はgetDate()らしい

//------ifをつかった条件分岐はここから------
if(myYou == 0 && myYou == 6){//もしもmyYouが0(日曜)と等しく,かつ(&&)6(土曜)と等しければ,
document.bgColor = "peru";//背景色を赤にせよ
kyouYoubi = "今日は土日のダイヤです"

//--土日の時の次のバス時間表示プログラムをここに

}
else{//それ以外の時は
document.bgColor = "powderblue";//背景色を白にせよ
kyouYoubi = "今日は平日のダイヤです"

//--平日の時の次のバス時間表示プログラムをここに

}
//----ifはここまで-------

//---ここは文字表示のシステム
document.getElementById("myYou_hyouji").innerHTML = kyouYoubi;//myYou_hyoujiというIDを検索してkyouYoubiを代入しなさい
//-----文字表示ここまで------

}//myByouのfunctionはここまで
</script>

<div id="myYou_hyouji"></div>
</body>
</html>

 

秒で背景色を変更する

なんかね,document.writeはあんまし使わんほうがいいかもです.

<!DOCTYPE html>
<html>
<head>
<title>Byou</title>
<meta charset="UTF-8">
</head>
<body>
<h1>Byou</h1>


<script type="text/javascript">
setInterval(myByou, 100);//myByouってfucitonを100ミリ秒おきに実行してね
//----

function myByou() {
myDate = new Date();//日付をとってきてmyDateにいれる.このfunctionの外に書くと1回しか日付をとってこないので,秒が更新されない
mySeconds = myDate.getSeconds();//myDateの中から秒だけとりだす.getSeconds()がその機能

//------ifをつかった条件分岐はここから------
if(mySeconds > 44 && mySeconds < 60){//もしもmySecondsが44より大きく,かつ(&&)60より小さければ,
document.bgColor = "#ff0000";//背景色を赤にせよ
}
else{//それ以外の時は
document.bgColor = "#ffffff";//背景色を白にせよ
}
//----ifはここまで-------

//---ここは文字表示のシステム
document.getElementById("myByou_hyouji").innerHTML = mySeconds;//myByou_hyoujiというIDを検索してmySecondsを代入しなさい
//-----文字表示ここまで------

}//myByouのfunctionはここまで
</script>

<div id="myByou_hyouji"></div>
</body>
</html>

 

お天気情報をよそからもってくる

天気情報をどう使えばよいかとの質問がありましたので,走り書き

各種サイトで天気情報が公開されています.

今回は非商用ですので,無料で使えるサービスを利用して天気を表示してみましょう.

なお、こうしたサービスの多くは個人での利用を前提としており、アプリ化して配布するなど、頻繁なアクセスをすり前提ではありませんので注意してください。
また、商用利用可能であっても、頻繁にアクセスしないようキャッシュを利用することがマナーとされています。

まず,こういうサービスのことをAPI(Application Programming Interface)と呼びます.ですので,Googleなどで”天気 API”などと検索するといくつか無料サービスが出てきます.このほかにも地図や交通情報などのAPIもあります.これらは”無料 API”で検索してみてください.

このほかにも”オープンデータ”などを利用してみても良いでしょう.

サンプルにはopenweathemapのAPIを利用しました.

次のHTMLをコピペしてブラウザで開いてみてください.(新JavaScript例文辞典さんの例文を利用しています)

<!DOCTYPE html>
<html>
<head>
<title>おてんき</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<!-- metaタグで スマホの挙動を制限している -->
</head>
<body>
<h1>てんき</h1>

<script type="text/javascript">


httpObj = new XMLHttpRequest();
httpObj.open("get", "http://api.openweathermap.org/data/2.5/weather?q=Nagoya,jp", true);
httpObj.onload = function(){
	var myData = JSON.parse(this.responseText);
	var txt = "";
	for (var i=0; i<myData.weather.length; i++){
		txt = txt + myData.weather[i].description + "  " + myData.weather[i].main+"<br>" + "<img src=http://openweathermap.org/img/w/" + myData.weather[i].icon + ".png>";
	}
	document.getElementById("result").innerHTML = txt;
	

}
httpObj.send(null);


</script>

<div id="result"></div>
<!-- このDIVのIDを探してここに21行目で作成したHTMLをいれちゃう -->

</body>
</html>

解説はいずれ

名古屋の天気情報が沢山出るのですが,そのうち,天気の記号とアイコンを引き出しています.

実際のデータは

http://api.openweathermap.org/data/2.5/weather?q=Nagoya,jp

です.この結果(JSON)から該当する部分を抜き出して,HTMLに入れています.

HTML5入門その23-写真にお絵かき4

さて,スクリプト全文です.

細かい装飾や表示位置は自分で変更してみてください.

<!DOCTYPE html>
<html>
<head>
<title>camera paint</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no">
<!-- metaタグで スマホの挙動を制限している -->
<script src="megapix-image.js"></script><!-- 外部の便利なライブラリを読み込んでいる -->
</head>
<body>
<h1>camera</h1>

カメラを起動,又は写真を選択<br>
<input type="file" accept="image/*" capture="camera" id="mycam" onchange="myCamera(mycam)"/>
<br>
<canvas id="myCanvas" style="border:1px solid #000000;"></canvas>

<script type="text/javascript">
var canvas;
var camCanvas;
var paintSwitch = false;
var oldX = 0;
var oldY = 0;
var myColor = "rgb(255,0,0)";//色を動的に変えられるようにするために変数宣言しちゃう
var myLine = 0;

//---スマホのOS取得
var ua = navigator.userAgent;//User Agent(まぁ機種名みたいなの)を取得して変数uaに代入しなさい
//---


//以下iPhoneの時の挙動
if (ua.indexOf("iPad") >= 0 || ua.indexOf("iPhone") >= 0 || ua.indexOf("iPod") >= 0){
//特に挙動はまだ決めていない
}

//以下Androidの時の挙動
if (ua.indexOf("Android") >= 0){
//特に挙動はまだ決めていない
}


//---------
window.onload = function() {//これ読み込んだ時に,,,
 syokika();//syokikaを実行してね
}

function syokika(){//で,これがsyokikaね
canvas = document.getElementById("myCanvas");

var context = canvas.getContext("2d");

//--ここからスマホのタッチの挙動<−NEW!!
canvas.addEventListener("touchmove",myTouchDraw,false);
canvas.addEventListener("touchstart",myTouchStart,false);
canvas.addEventListener("touchend",myTouchEnd,false);
}



//--タッチの挙動ここから
function myTouchStart(atai){
        paintSwitch = true;
        oldX = atai.touches[0].pageX - canvas.offsetLeft;//オフセット(ずれ)の修正=よこ
        oldY = atai.touches[0].pageY - canvas.offsetTop;//オフセット(ずれ)の修正=たて
}

function myTouchEnd(){
		paintSwitch = false;
}
//--タッチの挙動ここまで

//--カメラの画像
function myCamera(mycam){
	var myFile = mycam.files[0];
	new MegaPixImage(myFile).render(myCanvas, { width : 300});
}
//--カメラの画像処理ここまで


function myWidth(myWidth){
myLine = myWidth;
}



function myTouchDraw(atai) {
if (!paintSwitch) return;
	atai.preventDefault();//これすると縦スクロールがなくなる
	var x = atai.touches[0].pageX - canvas.offsetLeft;//なんかタッチの場合はpageXじゃないとだめ
    var y = atai.touches[0].pageY - canvas.offsetTop;//なんかタッチの場合はpageYじゃないとだめ
    var context = canvas.getContext("2d");
    context.strokeStyle = myColor;//色は動的に変えられるように変数にすちゃったよね
    context.lineWidth = myLine;//線の太さ
    context.beginPath();//線を描き始めます
    context.moveTo(oldX, oldY);//この点から
    context.lineTo(x, y);//この点まで
    context.stroke();//描いてね
    context.closePath();//線はここまで
    oldX = x;
    oldY = y;
}

function myRed(){
myColor = "rgb(255,0,0)";	
}
function myGreen(){
myColor = "rgb(0,255,0)";	
}
function myBlu(){
myColor = "rgb(0,0,255)";	
}
function myYel(){
myColor = "rgb(255,255,0)";	
}
function myGray(){
myColor = "rgb(128,128,128)";	
}
function myBlack(){
myColor = "rgb(0,0,0)";	
}

//---画像に変換ボタンを押すとここにfunctionが実行される
function screenshot(){
  var myimage = canvas.toDataURL();
  
  //以下iPhoneの時の挙動 上の方で機種をグローバル変数uaに入れてあるのでifで機種が分かる
if (ua.indexOf("iPad") >= 0 || ua.indexOf("iPhone") >= 0 || ua.indexOf("iPod") >= 0){
  document.getElementById("newImg").src = myimage;//newImgeというIDを探してPNG入れてね
}

  
//以下Androidの時の挙動 上の方で機種をグローバル変数uaに入れてあるのでifで機種が分かる
if (ua.indexOf("Android") >= 0){
    //androimageというiDがあるimgタグのソース(URL入れるところ)に入れちゃう
    document.getElementById("androimage").src = myimage;
}

    

}
//---

</script>


<form>
<input type="button" value="RED" onclick="myRed()">
<input type="button" value="GREEEN" onclick="myGreen()">
<input type="button" value="BLUE" onclick="myBlu()">
<input type="button" value="YELLOW" onclick="myYel()">
<input type="button" value="GRAY" onClick="myGray()">
<input type="button" value="BLACK" onClick="myBlack()">
</form>
</ br>
<pre>
線の太さ<input id="myRange" value="1" type="range" max="10" min="1" step="0.1" onChange="myWidth(this.value)" />
</pre>
<hr>
<form>
<input type="button" value="画像に変換" onclick="screenshot()">
<!-- onclickでscreenshotというfunction実行してね -->
</form>



<div><img id="newImg"></div>
<!-- iPhone用です このDIVのIDを探してここに画像を入れる -->
</ br>
<img src="" id="androimage" border="1"><!-- Androidの時の画像保存用 -->
<pre>
画像を長押しして保存
</pre>

</body>
</html>