
文字列の操作をちょっぴり解説します。文字列操作は僕の苦手分野なのでちょっぴり・・・。
前回のMetaCreationsフィルタによるトランジションで、配列に文字列を指定して代入していましたね。fName=["文字列1","文字列2",・・・]のようにカンマ,で各要素に入る文字列を区切っていました。
文字列操作によってもっと簡単にできるのでやってみましょう。
★sStrings.split(区切り文字,limit)・・・sStringsは文字列で、区切り文字によって分割されたときの文字列の配列を返します。limitは省略可能で、配列に返される要素の数を制限する値を指定します。split()はStringオブジェクトのメソッドで、返リ値は勿論文字列の配列です。
var moji="こんばんは".split("ん")・・・moji[0]="こ"、moji[1]="ば"、moji[2]="は"となります。文字列"ん"が区切り文字となり、分割されて配列になります。mojiは配列を代入することになるため、配列オブジェクトになります。
前回のスライドショーでは次のようになっていますね。
metafilter[0]=["ColorFade","GlassBlock","Liquid","Twister","CenterCurls","PageCurl","Water","LightWipe","RollDown","Wormhole","Lens","FadeWhite","Jaws","FlowMotion","Vacuum","Grid","Threshold","Ripple","Curls","PeelABCD","Curtains","BurnFilm"]//効果名用
metafilter[1]=["{2A54C908-07AA-11D2-8D6D-00C04F8EF8E0}","{2A54C913-07AA-11D2-8D6D-00C04F8EF8E0}","{AA0D4D0A-06A3-11D2-8F98-00C04FB92EB7}","{107045CF-06E0-11D2-8D6D-00C04F8EF8E0}","{AA0D4D0C-06A3-11D2-8F98-00C04FB92EB7}","{AA0D4D08-06A3-11D2-8F98-00C04FB92EB7}","{107045C5-06E0-11D2-8D6D-00C04F8EF8E0}","{107045C8-06E0-11D2-8D6D-00C04F8EF8E0}","{9C61F46E-0530-11D2-8F98-00C04FB92EB7}","{0E6AE022-0C83-11D2-8CD4-00104BC75D9A}","{107045CA-06E0-11D2-8D6D-00C04F8EF8E0}","{107045CC-06E0-11D2-8D6D-00C04F8EF8E0}","{2A54C904-07AA-11D2-8D6D-00C04F8EF8E0}","{2A54C90B-07AA-11D2-8D6D-00C04F8EF8E0}","{2A54C90D-07AA-11D2-8D6D-00C04F8EF8E0}","{2A54C911-07AA-11D2-8D6D-00C04F8EF8E0}","{2A54C915-07AA-11D2-8D6D-00C04F8EF8E0}","{AA0D4D03-06A3-11D2-8F98-00C04FB92EB7}","{AA0D4D0E-06A3-11D2-8F98-00C04FB92EB7}","{AA0D4D10-06A3-11D2-8F98-00C04FB92EB7}","{AA0D4D12-06A3-11D2-8F98-00C04FB92EB7}","{107045D0-06E0-11D2-8D6D-00C04F8EF8E0}"]//Copyright用
これを文字列から区切り文字を使用して分割して配列オブジェクトにするように変更します。区切り文字は何でもいいのですが、カンマ,にしてみました。
metafilter[0]="ColorFade,GlassBlock,Liquid,Twister,CenterCurls,PageCurl,Water,LightWipe,RollDown,Wormhole,Lens,FadeWhite,Jaws,FlowMotion,Vacuum,Grid,Threshold,Ripple,Curls,PeelABCD,Curtains,BurnFilm".split(",")//効果名用
metafilter[1]="{2A54C908-07AA-11D2-8D6D-00C04F8EF8E0},{2A54C913-07AA-11D2-8D6D-00C04F8EF8E0},{AA0D4D0A-06A3-11D2-8F98-00C04FB92EB7},{107045CF-06E0-11D2-8D6D-00C04F8EF8E0},{AA0D4D0C-06A3-11D2-8F98-00C04FB92EB7},{AA0D4D08-06A3-11D2-8F98-00C04FB92EB7},{107045C5-06E0-11D2-8D6D-00C04F8EF8E0},{107045C8-06E0-11D2-8D6D-00C04F8EF8E0},{9C61F46E-0530-11D2-8F98-00C04FB92EB7},{0E6AE022-0C83-11D2-8CD4-00104BC75D9A},{107045CA-06E0-11D2-8D6D-00C04F8EF8E0},{107045CC-06E0-11D2-8D6D-00C04F8EF8E0},{2A54C904-07AA-11D2-8D6D-00C04F8EF8E0},{2A54C90B-07AA-11D2-8D6D-00C04F8EF8E0},{2A54C90D-07AA-11D2-8D6D-00C04F8EF8E0},{2A54C911-07AA-11D2-8D6D-00C04F8EF8E0},{2A54C915-07AA-11D2-8D6D-00C04F8EF8E0},{AA0D4D03-06A3-11D2-8F98-00C04FB92EB7},{AA0D4D0E-06A3-11D2-8F98-00C04FB92EB7},{AA0D4D10-06A3-11D2-8F98-00C04FB92EB7},{AA0D4D12-06A3-11D2-8F98-00C04FB92EB7},{107045D0-06E0-11D2-8D6D-00C04F8EF8E0}".split(",")//Copyright用
いかがでしょう?
また
var setumei=["クリスマスツリー","鶴の夫婦","雪山","海に沈む夕日"]//説明文
も同様に
var setumei="クリスマスツリー,鶴の夫婦,雪山,海に沈む夕日".split(",")//説明文
とすることができますね。
では正常に動作することを確認ください。
ひな形において文字列操作がよく利用されるのはTickerというステータスバーに点滅メッセージを流す場合に見受けられます。
ステータスバーに文字列を表示するにはwindowオブジェクトのstatusプロパティを使用します。
★window.status・・・ステータスバーに文字列を設定または所得する。windowプリフィックスは省略可能である。
例)window.status="ステータスバーに文字を表示"
Tickerについてはまた別の機会にやってみたいと思います。
では音楽の歌詞を表示するひな形を作成してみたいと思います。これには準備が必要です。OutlookExpressでは音楽を流す際にbgsoundタグを使用します。また添付できるファイルとしてはmidiかwavファイルに限られますので、ここではmidiファイルを使用します。
歌詞の表示開始時間を演奏スタートを基点として秒数を計測しておきます。計測するためには演奏時間を表示できるソフトを使用するといいですね。
下図は松田聖子「風立ちぬ」のmidiをTMIDI PLAYERで演奏しながら、予めテキストエディタで開いた歌詞に時間を入力中のものです。

僕なりに時間を得たもの。aは1分を、bは2分を、cは3分を、dは4分を示しています。

midiファイル:kazetatinu_gs.mid
これを配列に入れます。kasi配列オブジェクトを作成し、二次元配列にします。時間用にkasi[0]を配列にし、歌詞用にkasi[1]を配列にして要素として入れます。
var kasi=new Array()
kasi[0]="0,14,22,37,52,66,74,89,103,110,118,125,132,140,162,177,191,199,206,213,221,234,241,248,256,264,287".split(",")
kasi[1]="松田聖子「風立ちぬ」,風立ちぬ
今は秋,今日から私は 心の旅人,涙顔見せたくなくて スミレひまわりフリージア,高原のテラスで手紙
風のインクでしたためています,SAYONARA SAYONARA SAYONARA・・・,振り向けば色づく草原
一人で生きてゆけそうね,首に巻く赤いバンダナ もう泣くなよとあなたがくれた,SAYONARA
SAYONARA SAYONARA・・・,風立ちぬ 今は秋,帰りたい帰れない あなたの胸に,風立ちぬ
今は秋,今日から私は 心の旅人,【間奏】,性格は明るいはずよ スミレひまわりフリージア,心配はしないでほしい
別れはひとつの旅立ちだから,SAYONARA SAYONARA SAYONARA・・・,草の葉に くちづけて,忘れたい忘れない
あなたの笑顔,想い出に目を伏せて,夏から秋への 不思議な旅です,風立ちぬ 今は秋,帰りたい帰れない
あなたの胸に,風立ちぬ 今は秋,今日から私は 心の旅人,【End】,stop".split(",")
一番最後の287とstopは曲の演奏終了を示します。
この要素の数はlengthプロパティで取得できますね。時間と歌詞は対応しているので、kasi[0].lengthとkasi[1].lengthは同じであるはずです。
さあここからが結構大変なんです。演奏中の時間をお知らせしてくれるプロパティはありません。WindowMediaPlayerの場合ですと、シークタイムを取得できますが、bgsoundタグではだめ(<object>タグならWindowsMediaPlayerを指定してシークタイムの取得が可能ですが、メールでは使えません)。
ここではアイディアが必要になります。演奏開始時間を記録しておいて、現在の時間との差を演奏経過時間にするという考えです。
演奏開始した時にまずその時間を記録しておきます。そして随時現在時間との差を計測します。
現在時間を収録するには?
現在のパソコン内の日付や時間は日付オブジェクトを作成した時に、その日付や時間が日付オブジェクトに格納されます。
★var sTime=new Date()・・・日付オブジェクトを作成する。このときパソコンの日付や時間が作成された日付オブジェクトに保存される。随時更新はされないので注意!!
作成した時の日付や時間が保存されます。つまり演奏スタート時にまず作成しておかなければなりません。また時間差を計算するためには、その時々の時間も取得しなければなりません。計測する際に新たに日付オブジェクトを作成しなければならないということになります。
var nowTime=new Date()
時間差はどうなりますか?というか日付オブジェクトには時間だけではなく、年・月・日・曜日・時・分・秒などが入っています。ユーザーの時間表示設定(コントロールパネルの日付と時刻設定)に従って表示されます。
<script>
var sTime=new Date()
status="Dateオブジェクトの内容="+sTime
</script>
サンプル
・・・更新させると時間が変わっているのがわかるはずです。
日付オブジェクトもオブジェクトですから、プロパティやメソッドが用意されています。
constructor プロパティ | prototype プロパティ
getDate メソッド | getDay メソッド | getFullYear メソッド | getHours メソッド | getMilliseconds メソッド | getMinutes メソッド | getMonth メソッド | getSeconds メソッド | getTime メソッド | getTimezoneOffset メソッド | getUTCDate メソッド | getUTCDay メソッド | getUTCFullYear メソッド | getUTCHours メソッド | getUTCMilliseconds メソッド | getUTCMinutes メソッド | getUTCMonth メソッド | getUTCSeconds メソッド | getVarDate メソッド | getYear メソッド | setDate メソッド | setFullYear メソッド | setHours メソッド | setMilliseconds メソッド | setMinutes メソッド | setMonth メソッド | setSeconds メソッド | setTime メソッド | setUTCDate メソッド | setUTCFullYear メソッド | setUTCHours メソッド | setUTCMilliseconds メソッド | setUTCMinutes メソッド | setUTCMonth メソッド | setUTCSeconds メソッド | setYear メソッド | toGMTString メソッド| toLocaleString メソッド | toUTCString メソッド| toString メソッド| valueOf メソッド| parse メソッド | UTC メソッド
この内、getTime()メソッドを使用しましょう。
object.getTime()メソッド・・・Date オブジェクトに格納されている時刻を返します。getTime メソッドの戻り値は、1970 年 1 月 1 日午前 00:00:00 と Date オブジェクトに格納されている時刻との差をミリ秒単位で表す整数値です。使用できる日付の範囲は、概算で 1970 年 1 月 1 日午前 00:00:00 から 285,616 年 12 月 31 日午後 12:59:59 までです。負の数値は、1970 年以前の日付を示します。
例)
var sTime=new Date()
var mTime=sTime.getTime()
ミリ秒単位であることに注意しなければなりません。今回では秒単位で演奏経過時間によって歌詞を表示させます。ミリ秒を秒に変更する際には1000で割ってから小数部分を切り捨てあるいは四捨五入などの処理をしたほうがいいでしょう(しなくてもよいと思いますが)。
ではひな形の準備をします。まず歌詞表示のエレメントを用意します。divエレメントを使用しましょう。idはkasistageとしました。
またボタンを押すとスタートするようにします。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<meta
http-equiv="content-type" content="text/html; charset=shift_jis">
<META
http-equiv="Content-Style-Type" content="text/css">
<title></title>
</head>
<body
style="margin:0px; padding:0px;">
<div id="kasistage"
style="padding:10px; position:absolute; z-index:2; left:20px; top:20px;
background-color:black; color:white; font-size:12pt; width:500px; height:500px;
overflow-y:auto"></div>
<input type="button"
name="b1" value="演奏開始" style="position:absolute;
left:220px; top:550px">
</body>
</html>
overflow-yはInternetExplorer6.0以降での対応です。注意してくださいね。
overflow-y:auto・・・コンテンツが縦方向の表示領域から外にあふれた時にスクロールバーを表示させて表示できるようにする。スクロールバーの表示は自動で行われる。IE6.0 or Later
スクリプト部分を考えて行きましょう。
歌詞表示のポインタをkpointとします。最初は0からですね。
var kpoint=0
演奏スタートは何かイベントに結びつけるか、スクリプトから開始させます。midiを演奏するのはbgsoundタグですね。bgsoundタグにsrc指定するとそのななでは勝手に演奏スタートします。そこでスクリプトでsrcを削除してしまいますが、単に削除するとファイル参照できなくなりますので、変数に一旦入れます。メールではフルパスにしますが、ここではWEBなので相対パス指定にしてあります。srccを空白にするにはnull("")を入れます。
<bgsound id="bgs" src="kazetatinu_gs.mid" volume="-200"
loop="1">
<script>
var sound=bgs.src
bgs.src=""
</script>
上の場合はsound変数にsrcを保存にしておいてから空白にしています。
演奏させるにはbgs.src=soundとすればよいのはお分かりでしょう。loop="1"なので一回だけ演奏します。時間をおいて演奏ならsetTimeout("bgs.src=sound",タイマー時間)ですね。クリックイベントで演奏ならonclick="bgs.src=sound"ですね。但しクリックで何度も実行が起こらないように考えておかなければなりませんよ。
ここでは関数でスタートさせましょう。bgmstart()関数定義します。スタート時はkpointは0ですからこれもセットしておきましょうか。サイドスタートさせる時にkpointが0になりますからね。また演奏中であれば関数を実行させないようにしましょう。これにはフラグを使用します。フラグとしてのflは演奏していない時0に、演奏している時は1にします。
flが0ではないときには関数を抜ける・・・if(fl!=0)return・・・a!=bはaがbと等しくない時でしたね。
演奏開始したらすぐにこのときの時間を取得しておきます。
var fl=0
var sTime,mTime//sTimeとsmTime変数を確保
function bgmstart(){
if(fl!=0)return
fl=1
bgs.src=sound
kpoint=0
mTime=(sTIme=new
Date()).getTime()
}
上の赤いところちょっと見かけないかもしれませんが、このような記述もできます。式の中に式を書くことも可能なんですね。下の青い部分も同じです。
現在時間取得ですが、演奏中に刻一刻と変わる時間をモニタするようにします。そのためには短い時間で繰り返し時間を取得します。尚flが0の時は演奏中ではないのですから現在時間取得する関数も実行する必要ありません。if(fl==0)returnも入れておきましょう。
var gTime,nTime
function nowgetTime(){
if(fl==0)return
nTime=(gTime=new
Date()).getTime()
setTimeout("nowgetTime()",500)
}
setTimeout("nowgetTime()",500)・・・これは500ミリ秒(0.5秒)ごとに時間を取得するための繰り返しになります。
この関数nowgetTime()もスタート関数から実行させます。
function bgmstart(){
if(fl!=0)return
fl=1
bgs.src=sound
kpoint=0
mTime=(sTIme=new
Date()).getTime()
nowgetTime()
}
さあ歌詞表示ですね。
関数にしましょう。ポインタkpointは最初は0ですね。演奏経過時間は?
現在の時間から演奏開始時の時間を引いたものは差(ミリ秒単位)になります。共に1970 年 1 月 1 日午前 00:00:00を起点にしていますから、問題ありませんね。この差を秒にしてから小数点以下を切捨てします。条件式は次のようになります。
Math.floor((nTime-mTime)/1000)>=kasi[0][kpoint]
この差がポインタkpointが示す歌詞表示のタイミング時間kasi[0][kpoint]以上になったら歌詞を表示させます。このときの歌詞の内容はkasi[1][kpoint]です。
if(Math.floor((nTime-mTime)/1000)>=kasi[0][kpoint]){処理}
表示後はkpointがいつまでも表示済みのポインタ値であることは無意味です。次の歌詞表示のために用意しなければなりません。kpoint++(インクリメント)。a++はa=a+1と同じです。インクリメント覚えてますか?1加算することでしたね。1減算するのはデクリメントです。
ところでkpointはどこまで増えることが可能でしょうか?歌詞の総数はkasi[1].lengthですが、一番最後の要素は演奏終了ですね。一番最後の要素はkasi[1][kasi[1].length-1]です。kpointがkasi[1].lengthになった時点(演奏終了)で関数から抜けますが、抜けるときに演奏中であることを示すフラグflを1から0に戻しましょう。
歌詞をどのように表示させるか?
divエレメントにはkasistageというidを付けていますから、内部コンテンツとして歌詞を表示させるテキストあるいはHTMLソースを書き加えればいいですね。これにはinherHTMLかinsertAdjacentHTML()を使用できることは既に学習済みです。
単にテキストとして加えるのではなく、HTMLタグで加えましょうか。
kasistage.innerHTML+='<span id="sp'+kpoint+'" style="color:rgb(255,0,0)">'+kasi[1][kpoint]+'</span><br>'
a+=b・・・a=a+bですね。<br>によって改行させます。colorの部分ですが、CSSではrgb(r,g,b)の形式も可能です。r,g,bはそれぞれ0〜255までの整数値です。赤青緑それぞれ256段階で強さを設定できます。ここではrgb(255,0,0)ですから赤になります。
歌詞表示用関数kasiView(){}
もしまだ差以上になっていない場合はまたこの関数に戻って判定させる・・・繰り返さなければなりません。繰り返し秒数も0.5秒にしましょう。
function kasiView(){
if(Math.floor((nTime-mTime)/1000)>=kasi[0][kpoint]){
kasistage.innerHTML+='<span
id="sp'+kpoint+'" style="color:rgb(255,0,0)">'+kasi[1][kpoint]+'</span><br>'
kpoint++
if(kpoint=kasi[1].length){
kpoint=0
fl=0
return
}
}
setTimeout("kasiView()",500)
}
idのところこのスクリプトでは不要ですが、後からいじるので歌詞のエレメント(span)を識別させるために入れておきました。kpointは変数なので、文字列に変数の内容を連結させる記述になっています。注意が必要です。kpointが0の時はidがsp0となりますね。
歌詞表示関数もスタート関数から実行させます。
function bgmstart(){
if(fl!=0)return
fl=1
bgs.src=sound
kpoint=0
mTime=(sTIme=new
Date()).getTime()
nowgetTime()
kasiView()
}
ではまとめましょう。ボタンクリックでスタートを忘れずに。onclick="bgmstart()"
[ソース]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
<head>
<meta
http-equiv="content-type" content="text/html; charset=shift_jis">
<META
http-equiv="Content-Style-Type" content="text/css">
<title></title>
</head>
<body
style="margin:0px; padding:0px;">
<div id="kasistage"
style="padding:10px; position:absolute; z-index:2; left:20px; top:20px;
background-color:black; color:white; font-size:12pt; width:500px; height:500px;
overflow-y:auto"></div>
<input type="button"
name="b1" value="演奏開始" onclick="bgmstart()"
style="position:absolute; left:220px; top:550px">
<bgsound
id="bgs" src="kazetatinu_gs.mid" volume="-200"
loop="1">
<script>
var sound=bgs.src
bgs.src=""
var
kasi=new Array()
kasi[0]="0,14,22,37,52,66,74,89,103,110,118,125,132,140,162,177,191,199,206,213,221,234,241,248,256,264,287".split(",")
kasi[1]="松田聖子「風立ちぬ」,風立ちぬ
今は秋,今日から私は 心の旅人,涙顔見せたくなくて スミレひまわりフリージア,高原のテラスで手紙
風のインクでしたためています,SAYONARA SAYONARA SAYONARA・・・,振り向けば色づく草原
一人で生きてゆけそうね,首に巻く赤いバンダナ もう泣くなよとあなたがくれた,SAYONARA
SAYONARA SAYONARA・・・,風立ちぬ 今は秋,帰りたい帰れない あなたの胸に,風立ちぬ
今は秋,今日から私は 心の旅人,【間奏】,性格は明るいはずよ スミレひまわりフリージア,心配はしないでほしい
別れはひとつの旅立ちだから,SAYONARA SAYONARA SAYONARA・・・,草の葉に くちづけて,忘れたい忘れない
あなたの笑顔,想い出に目を伏せて,夏から秋への 不思議な旅です,風立ちぬ 今は秋,帰りたい帰れない
あなたの胸に,風立ちぬ 今は秋,今日から私は 心の旅人,【End】,stop".split(",")
var
fl=0
var sTime,mTime//sTimeとsmTime変数を確保
function bgmstart(){
if(fl!=0)return
fl=1
bgs.src=sound
kpoint=0
mTime=(sTIme=new
Date()).getTime()
nowgetTime()
kasiView()
}
var
gTime,nTime
function nowgetTime(){
if(fl==0)return
nTime=(gTime=new
Date()).getTime()
setTimeout("nowgetTime()",500)
}
function
kasiView(){
if(Math.floor((nTime-mTime)/1000)>=kasi[0][kpoint]){
kasistage.innerHTML+='<span
id="sp'+kpoint+'" style="color:rgb(255,0,0)">'+kasi[1][kpoint]+'</span><br>'
kpoint++
if(kpoint=kasi[1].length){
kpoint=0
fl=0
return
}
}
setTimeout("kasiView()",500)
}
</script>
</body>
</html>
歌詞表示「松田聖子:風立ちぬ」midi:TAXI打ち込み
・・・じつはこれ問題があります。いやエラーじゃなくて問題でもないのですが、演奏終了後にボタンを押すと前回の歌詞が消えずに二回目以降つながっていきます。スタート関数に歌詞表示をクリアする命令がありません。kasistage.innerHTML=""とすると消えますね。
function bgmstart(){
if(fl!=0)return
fl=1
bgs.src=sound
kasistage.innerHTML=""
kpoint=0
mTime=(sTIme=new
Date()).getTime()
nowgetTime()
kasiView()
}
歌詞表示改良タイプ「松田聖子:風立ちぬ」midi:TAXI打ち込み![]()
歌詞の色が変わる歌詞表示改良タイプ「松田聖子:風立ちぬ」midi:TAXI打ち込み![]()
次回も文字列操作・文字列から文字の抽出をやってみます。