ひな形スクリプト講座10

 

[ひな形スクリプト講座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][参考資料索引]

今回のテーマは・・・まだ決めていなかったですね。

まず次のサンプルをご覧ください。

アキアカネが羽ばたく?

どうでしょうか?トンボは羽ばたいていますか?羽ばたいてない?ん〜そうですねぇ。僕のパソコンではばたいて見えます。実はトンボの画像はアニメーションGIF画像なんです。羽ばたいて見えない方のパソコンはかなり古いものとお見受けします。このサンプルではスクリプト処理はそれほど負荷が大きなものではありませんから、大抵は羽ばたいて見えるはずなのです。それでも羽ばたいて見えないのは、他に負荷のかかるソフトが実行されているためか、余程古いパソコンで処理能力が低いかどちらかだと推測されます。

akiakane_ani.gif

で、羽ばたいて見える方でも安心できません。もっと処理の複雑なスクリプトですと、IEもOEもパソコンの処理にパワーが必要になります。場合によってはアニメーションGIFが停止画像のように見えてしまいます。これはスクリプト処理をできるだけ優先するからでです。この傾向はmarqeeによる移動にも見られます。スクリプト処理にある程度の負荷がかかる場合、gifアニメーションやマーキー移動処理は後回しにされるんです。尚スクリプトではなく、HTML+TIMEを使った場合でもスクリプト同様に負荷がかかることが多くなります。やはりHTML+TIMEの処理が優先されます。フィルタを適用しているエレメントが表示される場合特に負荷は増えますので、フィルタをかけるのは程々にしましょう。

ではアニメーションGIFが動かない場合に、トンボを羽ばたかせたい場合はどうしましょう?スクリプトでアニメーションしているように見せられれば・・・・なんだか希望が出てきますね。

トンボの羽ばたきはとりあえず二つの画像を用意しました。画像は縮小表示しています。

akiakane.gif          akiakane2.gif

このふたつは縦サイズが違うように見えますが、実際はサイズはまったく同じように作っています。枠線をつけて確認しておきますね。
    

 このふたつの画像をスクリプトでimg1エレメントに交互に入れ替えれば羽ばたいているように見えそうですね。

 imgエレメントに画像を指定するには、img1.src="画像ファイル名"で可能です。画像ファイル名はフルパスでも相対パスでも構いません。しかしここでは変数に二つの画像(srcの内容)を入れてしまい、その変数の内容をimg1のsrcにしてしまいましょう。

変数は二つ用意して使用してもいいのですが、変数には配列変数という便利な入れ物も使用できるように設計されています。
JavaScriptの場合は配列変数は配列オブジェクトとも呼ばれています。

配列オブジェクトの作成
var 配列オブジェクト名=new Array()

 通常の変数との違いはnewキーワードを使用して配列であるArray()を記述して作成するのが基本です。これはあくまでも基本であり、他にもいろいろな方法があります。ここでは直接配列変数に要素を入れて使用します。

var 配列オブジェクト名=[要素1,要素2,・・・]
配列変数に代入する要素をカンマ区切りで記述します。要素の数により、配列変数の要素数が決まります。

配列変数にはコレクション同様の扱いをします。変数自身がオブジェクトだから、そのデータ構造はオブジェクトのコレクションになります。勿論変数と同様文字列・数値・オブジェクトなどを収めることができます。

ではまず画像をメールで送れるようにするにはimgエレメントにsrcでファイル指定するのが必修ですから次のようにします。

<img id="img1" src="akiakane.gif" style="filter:Alpha(opacity=100); position:absolute; left:0px; top:100px; width:100px">
<img id="img2" src="akiakane2.gif" style="position:absolute; left:-2000px">

leftが-2000pxとなっているのは、akiakane2.gif(img2エレメント)が表示されないようにするためです。これはひな形での常套手段ですね。

先に述べたように配列変数にakiakane.gifとakiakane2.gifを代入しましょう。

var imgfile=[img1.src,img2.src]

これでimgfile[0]にはimg1.srcであるakiakane.gifが、imgfile[1]にはimg2.srcであるakiakane2.gifが代入されました。

さてaが整数である時、aがどんな値であっても、0からbまでの値をとるような式は、剰余という算術演算子を使用します。
a%(b+1)・・・但しbも整数

例)aがどのような値でも0〜5までの値をとる
a%6
aが0の時は6で割った余りは0、aが1の時は1、aが2の時は2、aが3の時は3,、aが4の時は4、aが5の時は5、aが6の時は6で割ると余りは0、・・・というようになりますね。

a%bはaをbで割った余りを得ます。

aに1足してその値をbで割った余りをaに代入するとaの値は必ず0以上b未満の整数になります。これもとてもよく使われるので、覚えておいて損はありません。

いきなり剰余の計算を解説して今回のテーマに関係あるの?

あっいいところに気がつきました。どこかにこの剰余計算が必要なのかと思いますよね。結論は必要といえば必要だし、必要ではないといえば必要ではないんです。

imgfile配列オブジェクトにはコレクションとして、img1.srcとimg2.srcの内容が入ってますね。そのコレクションを番号で表すと、imgfile[0]とimgfile[1]ですね。番号は0か1を使うということに気がつきませんか?

では二つの画像を交互に入れ替えるというのはどういうことでしょう?これは現在img1.srcである時に次に処理する時にはimg2.srcにする。img2.srcの時は次の処理ではimg1.srcにするということですね。そしてこのimg1.srcとimg2.srcはimgfile[0]とimgfile[1]ですね。

ということはimgfile[0]というのはaが0の時に当てはめる、imgfile[1]というのはaが1の時に当てはめると考えられますね。このaは0=>1=0=>1・・・と交互に変化します。
このような変化をつける方法を考えてみると、剰余計算で求めるという方法もあることを言いたかったんです。必要ではないというのは、他にも方法があるからです。

aが0の時aを1にする、aが1の時aを0にするこれを簡単な計算で行う方法それが今回の大きなテーマです。

@aの初期値を0とし、a=1-aの計算をする
どうでしょう。aが1の時1-aは0になりますね。aが0の時は1-aは1になります。見事クリアできますね。

Aaの初期値を0とし、a=(a+1)%2の計算をする
これはどうでしょう。aがoの時a+1は1ですね。1を2で割った余りは1です。aが1の時はa+1は2です。2を2で割った余りは0です。これも見事にクリアです。

@の方が簡単そうなんだけど・・・

そうですね。でもある思惑があってAを使用することにします。その意味については後で解説しますね。

画像の交換を行うスクリプトも関数にしてしまいましょう。もうわかりますね。

var a=0
function imgchange(){
a=(a+1)%2
img1.src=imgfile[a]

}

この関数を実行する場所は、右移動する処理か左移動する処理のところにしましょう。

[ソース]

<html>
<head>
<title></title>
</head>
<body style="margin:0px; overflow:hidden">
<img id="img1" src="akiakane.gif" style="filter:Alpha(opacity=100); position:absolute; left:0px; top:100px; width:100px">
<script>
var ix=5//一度に動くピクセル数
var iy=5//一度に動くピクセル数(縦)
var rtime=30//繰り返し実行時間(ミリ秒)少し遅くしてみました
function lidou(){//右移動する関数
status="ix="+ix+" ;iy="+iy
if(img1.style.pixelLeft+ix>=document.body.clientWidth-img1.clientWidth){
   if(img1.style.pixelLeft<document.body.clientWidth-img1.clientWidth){
       imgchange()
       opchange()
       img1.style.pixelLeft=document.body.clientWidth-img1.clientWidth
   }else{
       ixchange()
       ridou()
       return
   }
}else{
   imgchange()
   opchange()
   img1.style.pixelLeft+=ix
}
//status=img1.style.pixelLeft
setTimeout("lidou()",rtime)
}

function ridou(){//左移動する関数
status="ix="+ix+" ;iy="+iy
if(img1.style.pixelLeft>0){
opchange()
imgchange()
   if(img1.style.pixelLeft-ix<0){
       img1.style.pixelLeft=0
   }else{
       img1.style.pixelLeft-=ix
   }
   setTimeout("ridou()",rtime)
}else{
ixchange()
lidou()
return
}
}

function didou(){//下移動する関数
if(img1.style.pixelTop+iy>=document.body.clientHeight-img1.clientHeight){
   if(img1.style.pixelTop<document.body.clientHeight-img1.clientHeight){
       img1.style.pixelTop=document.body.clientHeight-img1.clientHeight
   }else{
       iychange()
       uidou()
       return
   }
}else{
   img1.style.pixelTop+=iy
}
setTimeout("didou()",rtime)
}


function uidou(){//上移動する関数
if(img1.style.pixelTop>0){
   if(img1.style.pixelTop-iy<0){
       img1.style.pixelTop=0
   }else{
       img1.style.pixelTop-=iy
   }
   setTimeout("uidou()",rtime)
}else{
iychange()
didou()
return
}
}

var saikoro=Math.floor(Math.random()*4)+1
switch(saikoro){
case 1:
img1.style.pixelLeft=-img1.clientWidth
img1.style.pixelTop=Math.floor(Math.random()*(document.body.clientHeight+img1.clientHeight+1))-img1.clientHeight
break
case 2:
img1.style.pixelTop=-img1.clientHeight
img1.style.pixelLeft=Math.floor(Math.random()*(document.body.clientWidth+img1.clientWidth+1))-img1.clientWidth
break
case 3:
img1.style.pixelLeft=document.body.clientWidth
img1.style.pixelTop=Math.floor(Math.random()*(document.body.clientHeight+img1.clientHeight+1))-img1.clientHeight
break
case 4:
img1.style.pixelTop=document.body.clientHeight
img1.style.pixelLeft=Math.floor(Math.random()*(document.body.clientWidth+img1.clientWidth+1))-img1.clientWidth
}

var flag=0
function clstart(){
if(flag==0){
ixchange()
iychange()
lidou()
didou()
}
flag=1
}

function ixchange(){
ix=Math.floor(Math.random()*46)+5
}

function iychange(){
iy=Math.floor(Math.random()*46)+5
}

var kagen=-5
function opchange(){
if(img1.filters["alpha"].opacity+kagen>100)kagen=-kagen
if(img1.filters["alpha"].opacity+kagen<0)kagen=-kagen
img1.filters["alpha"].opacity+=kagen
}

var a=0
var imgfile=[img1.src,img2.src]
function imgchange(){
a=(a+1)%2
img1.src=imgfile[a]
}


document.onclick=clstart
</script>
</body>
</html>

スクリプトで羽ばたかせる

配列オブジェクトの基本的使い方に沿ったソースは
var a=0
var imgfile=new Array()
imgfile[0]=img1.src
imgfile[1]=img2.src

function imgchange(){
a=(a+1)%2
img1.src=imgfile[a]
}

スクリプトで羽ばたかせる2

 


さてなぜ@のa=1-aを使用しなかったかについてです。

もし入れ替える画像が二つではなく三つ、或いは四つ五つともっと多い場合、a=1-aは使えなくなりますね。
例えば三つの場合
var imgfile=[img1.src,img2.src,img3.src]のようになり、0=>1=>2=>0=>1=>2・・・の様にaの値を変化させる必要が出てきます。a=1-aではこのような変化は望めません。
a=2-aなどにしてもだめです。

ではAの場合はどうかというと、a=(a+1)%3とすればaの値は0=>1=>2=>0=>1=>2・・・と変化させることができます。Aの方法は汎用性があるんですね。

akiakane.gif          akiakane2.gif    akiakane3.gif

みっつ使用の例・・・このポイントは画像はみっつですが、コレクション数を四つにしていることです。img3.src(akiakane3.gif)を二回使用していることに注目。
var a=0
var imgfile=[img1.src,
img3.src,img2.src,img3.src]
function imgchange(){
a=(a+1)%
4
img1.src=imgfile[a]
status="a="+a+" ;画像="+img1.src

}

このトンボひな形はこれにて終了します。後は皆さんで考えてみてください。例えば端ではね返るのではなく、端から50ピクセル離れたところで方向転換する、或いは時折端に当たらなくても方向転換するとかも面白いかもしれません。

今回のテーマはアニメーションgifが動かないなら、スクリプトでその代用をしようというものでした。アニメーションgifにはフレームごとに表示時間が設定されているので、そのような動きに似せるためにはもっと作りこむ必要がありますが、今回のテーマはそのヒントになることでしょう。

次回からは別の素材を使用してみましょう。

 


[ひな形スクリプト講座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][参考資料索引]