![]() ![]() ![]() ![]() Silverlightで作るVistaガジェット「ギターチューナー」この記事のURLhttp://japan.internet.com/developer/20080115/26.html
著者:kirants
海外internet.com発の記事
はじめにそのとき、神は「光(Silverlight)あれ。」と言われた。すると光(Silverlight)があった。――さて、この「Silverlight」とは何なのでしょうか。Silverlightは、一言で言えば、Web向け次世代双方向コンテンツを作るためのMicrosoft流ソリューションです。XAMLとJavaScriptを使い、メディアを多用して双方向性を生かしたキラーアプリケーションを作ることができます。現在は、WPFのサブセットです。Silverlightの長所は、この開発フレームワークがクロスブラウザだという点です。プラグインをインストールするだけで、どこででも開発することができます。Macromedia(現Adobe Systems)のFlashに似ていますが、Silverlightの場合、アプリケーションを動かす実体(XAML)は完全なテキストですから、対検索エンジンでは有利です。 Silverlight(バージョン1.0)は、以前は「WPF/e」と呼ばれていました。現在はMicrosoftのWebサイトからダウンロードすることができます。なお、Microsoftは既にバージョン1.1のベータ版を開発者向けにリリースしています。 注
この記事の趣旨に従い、ここではバージョン1.0 RCを使います。
概要この記事では、Silverlightを使って気の利いた小さなガジェットを作ります。その制作を通して、Silverlightでよく使われるパーツやテクニックを実際に体験していただこうというのがこの記事の目的です。したがって、ここではSilverlightを深く掘り下げたり、サイドバーガジェットを詳細に説明したりすることはしません。それでは、準備として何を揃えておく必要があるのでしょうか。嬉しいことに必要なものはわずかで、次の3つだけです。
実際、ガジェットが関係してくるのは最後の段階だけで、そのわずかな作業を除けばVistaさえ不要です。作業のほとんどはファイルを編集することとブラウザの再読み込みだけですから、XPがあれば十分なのです。 ギターチューナー私はギターが大好きです。そこで、ギターチューナーを作ることにしました。この記事を読む人の中にギターファンが大勢いるとは思えませんが、ギターチューナーはとても簡単でVistaガジェットにはうってつけです。 ギターチューナーをご存じない方のために、ここで簡単に説明しておきましょう。ご存じの方は、ここを飛ばして次の節に進んでください。さて、ギターは弦楽器です。通常、6本の弦があり、それぞれ演奏しやすいように特定の音程に調整されます。ですから、それぞれの弦を弾くとその弦に固有の音が鳴ります。6本の弦は、普通、標準の音程に調整されますが、この作業を「調弦」(調律、チューニング)と呼んでいます。調弦は基本的に弦の発する音の相互関係であり、標準やDrop Dなどいくつかの種類があります。演奏者は演奏に先だってまずギターを調弦し、自分が演奏する際の舞台を整えます。調弦されていない弦からは雑音しか聞こえてきませんが、調弦された弦から紡ぎ出された音符は楽しげに響きます。ギターチューナーはこの調弦に使う道具です。6本の弦のそれぞれが鳴らすべき音を出し、演奏者は弦を弾きながらその音に合わせて弦を調整します。すべての弦がチューナーの音に合っていることを「ギターは調弦されている」と言います。今では、ほとんどの演奏者はノートパソコンを使ってポピュラーソングをオンラインで調べ、好みの歌を聴き、自分の曲を録音していますから、パソコン上にギターチューナーがあれば便利です。というわけで、このガジェットを作ろうと思いついたのです。 完成図下の図のようなガジェットを作るのが目標です。 ![]() どうです、ギターに見えませんか? ギターのように6本の弦があり、中央にはサウンドホールがあります(これがあるとギターっぽく見えますね)。必要な作業は次のとおりです。
以降では、実際にXAMLのいろいろな機能と若干のJavaScriptを使い、それらを組み合わせてギターチューナーを作っていきます。 完成したVistaガジェットは、格納状態ではこんな風になり、 ![]() サイドバーから出すとこんな風になるはずです。 ギターチューナーの外観を作る(その1)基本的な枠組みを準備するそれでは始めましょう。Silverlightプラグインはインストールしてありますか。もしまだなら、ここからダウンロードしてインストールします。もう1つ、SDKはいかがですか。まだなら、ここからダウンロードしてインストールします。 1「GuitarTuner.gadget」という名前のフォルダを作ります。 2このフォルダに「Silverlight.js」というファイルをコピーします。このファイルは、[ドライブ名]:¥Program Files¥Microsoft Silverlight 1.0 SDK¥Resourcesにあります。 3新たにテキストファイルを作り、その拡張子を.HTMLに変更して、「GuitarTuner.HTML」という名前にします。そして、次のテキストを貼り付けます。 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> <head> <title>Guitar Tuner</title> <script type="text/javascript" src="Silverlight.js"></script> </head> <body> </body> </html> 4 これは起動用のHTMLで、ここにSilverlightコントロールを記述します。まず、divタグを追加し、そこにSilverlightコントロールを作るJavaScriptコードを記述します。これで <body> <div id="SilverLightControlHost"> <script type="text/javascript"> var parentElement = document.getElementById("SilverLightControlHost"); createGuitarTunerControl(); </script> </div> </body> 5 次に、このコードに使われている 6このファイルに次のコードを貼り付けます。 function createGuitarTunerControl() { Silverlight.createObject( "guitarTuner.xaml", // Source property value. parentElement, // DOM reference to hosting DIV tag. "guitarTunerControl", // Unique plugin ID value. { // Per-instance properties. width:'400', // Width of rectangular region of // plugin area in pixels. height:'290', // Height of rectangular region of // plugin area in pixels. // Determines whether to display in-place // install prompt if invalid version detected. inplaceInstallPrompt:false, background:'Orange', // Background color of plugin. // Determines whether to display plugin in Windowless // mode. isWindowless:'true', framerate:'24', // MaxFrameRate property value. version:'1.0' // Silverlight version to use. }, { onError:null, // OnError property value -- // event handler function name. onLoad:null // OnLoad property value -- // event handler function name. }, null); // Context value -- event handler function name. } このコードは、Silverlightコントロールオブジェクトを実装しているXAMLファイル(guitarTuner.xaml)へのパスを渡し、実際にインスタンス化します。プラグインID(guitarTunerControl)は、 7HTMLファイルのhead部分に、このスクリプトファイルを使う旨の宣言を追加します。 <head> <title>Guitar Tuner</title> <script type="text/javascript" src="Silverlight.js"></script> <script type="text/javascript" src="guitartuner.js"></script> </head> 8まだ作っていないのはXAMLファイルだけです。そこで、もう1つテキストファイルを作り、拡張子を.xamlに変更して、「guitarTuner.xaml」という名前にします。 9次のコードを貼り付けます。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > </Canvas> 10これで、枠組みはできあがりです。それでは、「guitarTuner.HTML」をダブルクリックしてください。このHTMLがWebブラウザ上に読み込まれ、問題がなければ画面には次のようなオレンジ色の矩形が表示されるはずです。 ![]() ギターチューナーの外観を作る(その2)基本的な枠組みが用意できましたので、最初に紹介したギターチューナーを構成するパーツを作り込んでいきましょう。各パーツは次のようになっています。 ![]()
いずれもXAMLの要素を使い、円オブジェクトと停止ボタンはEllipseで、弦とブリッジはRectangleで表現することができます。EllipseもRectangleもShape要素に属し、塗りつぶし(図形の内部を塗りつぶすこと)や大きさなどのプロパティを持っています。 XAMLの要素は、すべてCanvas(従来のWin32で言えばDC)に置きます。キャンバスというのは子要素を置く場です。キャンバスにはコントロール要素(ボタンなど)、Shape要素(RectangleやEllipseなど)、メディア要素などのほか、別のキャンバスを置くこともできます。 こうした要素が集まって、下図のような階層的ツリー構造を作ります。 ![]() ですから、ここでの目標はギターチューナーのツリー構造を作ることだとも言えます。つまり、これからXAMLで木を作り、各要素の位置を指定していくわけです。ここで、XAMLでは木の一番上にあるものから下に向かって描画される点に注意してください。したがって、木の下にある図形は上にある図形の上に重ねて描画されます(これはデフォルトで、Zオーダーを明示的に変更することもできます)。 ギターチューナーの場合で言えば、XAMLファイルでは円オブジェクト(図の1)を最初に記述するということになります。重なっていない要素については、どのような順序でもかまいません。 各要素は、次の設計図に従って配置します。 1XAMLファイルを開き、Ellipse要素(設計図の黒い円)を表す下のコードを追加します。このコードは、Ellipse Shape要素をキャンバスの左上の角を基点(0, 0)として(30, 25)の位置に配置します。幅も高さも100ピクセル、つまり半径50ピクセルで、黒で塗りつぶします。Hollowという名前が付けてあるのは、あとでこの要素を指定する必要があるからです。それでは、XAMLファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <Ellipse x:Name="Hollow" Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> </Canvas> 2Zオーダーから言って、次はブリッジ(設計図の赤い矩形)です。今度は、Rectangle Shape要素を使います。親キャンバスを基準として位置と大きさを指定し、Bridgeという名前を付けます。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <Ellipse Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> <Rectangle x:Name="Bridge" Width="10" Height="90" Canvas.Left="10" Canvas.Top="30" > </Rectangle> </Canvas> 本物のギターではブリッジはかまぼこ形に作られているので、その雰囲気も再現したいですよね。実は、Fill属性を使うと簡単にそれらしく作ることができます。サウンドホールには色を一様に塗ります。穴を表現するにはこの方法が適しているからです。しかし、ブリッジのように膨らんだ感じを出すには、グラデーションの塗りを使用します。左端から中央に向けて黒から徐々に灰色になり、そこから右端に向けて再び黒くするのです。コードは次のようになります。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <Ellipse Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> <Rectangle x:Name="Bridge" Width="10" Height="90" Canvas.Left="10" Canvas.Top="30" > <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="Black" Offset="0.0"/> <GradientStop Color="Gray" Offset="0.5"/> <GradientStop Color="Black" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Canvas> コードを詳しく見てみましょう。 3Zオーダーから言って、次は弦(設計図の青い矩形)です。弦は6本ありますが、ここでは1本だけ取り上げて説明します(弦の位置を除き、設定の仕方はどの弦でも同じです)。ギターの弦は、上から下にそれぞれ、低いE、A、D、G、B、高いEの弦と呼びます。本物のギターでは、一番上の弦(一番低い音を出します)は太く、下に行くほど細くなります。XAMLでも、これを再現することにしましょう。そのためには矩形の高さを変えます。 弦は丸いので、その雰囲気も再現したいですよね。この場合も矩形とグラデーションを使えば再現できます。ただし、弦に似た色で縦方向にグラデーションします(ブリッジとは <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <Ellipse Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> <Rectangle x:Name="Bridge" Width="10" Height="90" Canvas.Left="10" Canvas.Top="30" > <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="Black" Offset="0.0"/> <GradientStop Color="Gray" Offset="0.5"/> <GradientStop Color="Black" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="LowEString" Width="315" Height="5" Canvas.Left="15" Canvas.Top="37"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> </Canvas> XAMLファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。 5最後は、停止ボタン(設計図の緑の円)です。サウンドホールのときと同じEllipse Shape要素を使います。立体的に見えるように、放射状のグラデーションを使いましょう。コードは次のようになります。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <Ellipse Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> <Rectangle x:Name="Bridge" Width="10" Height="90" Canvas.Left="10" Canvas.Top="30" > <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="Black" Offset="0.0"/> <GradientStop Color="Gray" Offset="0.5"/> <GradientStop Color="Black" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="LowEString" Width="315" Height="5" Canvas.Left="15" Canvas.Top="37"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Ellipse x:Name="StopButtonb" Height="15" Width="15" Canvas.Left="8" Canvas.Top="125" Stroke="Black" StrokeThickness="1" > <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="Red" Offset="1.0"/> <GradientStop Color="White" Offset="0.0"/> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> </Canvas> XAMLファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。 6残り5本の弦も入れて完成させます。コードは次のようになっているはずです。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" ><Ellipse Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> <Rectangle x:Name="Bridge" Width="10" Height="90" Canvas.Left="10" Canvas.Top="30" > <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="1,0"> <GradientStop Color="Black" Offset="0.0"/> <GradientStop Color="Gray" Offset="0.5"/> <GradientStop Color="Black" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="LowEString" Width="315" Height="5" Canvas.Left="15" Canvas.Top="37"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="AString" Width="315" Height="5" Canvas.Left="15" Canvas.Top="52"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="DString" Width="315" Height="4" Canvas.Left="15" Canvas.Top="67"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="GString" Width="315" Height="4" Canvas.Left="15" Canvas.Top="82"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="BString" Width="315" Height="3" Canvas.Left="15" Canvas.Top="97"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="HighEString" Width="315" Height="3" Canvas.Left="15" Canvas.Top="112"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Ellipse x:Name="StopButtonb" Height="15" Width="15" Canvas.Left="8" Canvas.Top="125" Stroke="Black" StrokeThickness="1" > <Ellipse.Fill> <RadialGradientBrush> <GradientStop Color="Red" Offset="1.0"/> <GradientStop Color="White" Offset="0.0"/> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> </Canvas> XAMLファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。下の図のようになりましたか? ![]() ギターチューナーに動作を加えるギターチューナーの外観ができたので、次に動作を加えましょう。ここでの目標は次の3つです。
第1の目標まず、第1の目標です。始めに、弦と停止ボタンの上にマウスを置いたとき、それらがクリックできることがわかるようにしなければなりません。このような場合、手の形のカーソルを使うのが普通です。そこで、XAMLファイルを再度開き、すべての弦と停止ボタンにCursor属性を追加します。コードは次のようになります。
<Rectangle x:Name="LowEString" Width="315" Height="5"
Canvas.Left="15" Canvas.Top="37" Cursor="Hand">
次に、弦がクリックされたときに所定の動作をするようマウスボタンハンドラを追加します。次のように、イベント名とハンドラ関数を設定します。このハンドラ関数はすべての弦で共通して使います。残り5本についても同じように追加します。
<Rectangle x:Name="LowEString" Width="315" Height="5"
Canvas.Left="15" Canvas.Top="37" Cursor="Hand"
MouseLeftButtonDown="stringPlucked">
メモ帳で「guitartuner.js」ファイルを開き、上のコードで指定した
function stringPlucked(sender, args)
{
}
この関数の中に必要な動作を書き込んでいきます。ここでは、弦が弾かれたら、その弦とブリッジが交差する点に緑のインジケータを点滅させます。まず、次のように、[弦の名前]Indicatorという名の要素を追加します。 <Rectangle x:Name="LowEString" Width="315" Height="5" Cursor="Hand" Canvas.Left="15" Canvas.Top="37" MouseLeftButtonDown="stringPlucked"> <Rectangle.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Color="Brown" Offset="0.0"/> <GradientStop Color="White" Offset="0.5"/> <GradientStop Color="Brown" Offset="1.0"/> </LinearGradientBrush> </Rectangle.Fill> </Rectangle> <Rectangle x:Name="LowEStringIndicator" Height="15" Width="10" Canvas.Left="10" Canvas.Top="30" Fill="#00FF00" Opacity="0.0" > </Rectangle> 少し説明しておきましょう。 次に、インジケータを点滅させます。そのため、 <Rectangle x:Name="LowEStringIndicator" Height="15" Width="10" Canvas.Left="10" Canvas.Top="30" Fill="#00FF00" Opacity="0.0" > <Rectangle.Resources> <Storyboard x:Name="LowEStringIndicatoranimation"> <DoubleAnimation Storyboard.TargetName="LowEStringIndicator" Storyboard.TargetProperty="Opacity" From="0.0" To="1.0" Duration="0:0:0.3" AutoReverse="True" RepeatBehavior="Forever" /> </Storyboard> </Rectangle.Resources> </Rectangle> 少し説明しておきましょう。まず あとは、このストーリーボードのアニメーションが起動されるようにすれば終わりです。そこで、次のコードを「guitartuner.js」ファイルの function stringPlucked(sender, args) { var storyboardObj = sender.findName(sender.Name + "Indicatoranimation"); storyboardObj.begin(); } XAMLファイルとJSファイルを保存し、ブラウザのHTMLファイルを再度読み込ませます。ここで、一番上の弦をクリックすると緑のインジケータが点滅するはずです。 ここで、この小さなJavaScriptコードについて若干補足しておきましょう。まず、とても便利な これで第1の目標は完成です。 第2の目標 次は第2の目標です。弦が鳴っているときに赤い停止ボタンが押されたら、先ほど実装したインジケータを消さければなりません。基本的に同じ方法で実装することができます。それでは、
<Ellipse x:Name="StopButtonb" Height="15" Width="15"
Canvas.Left="8" Canvas.Top="125" Stroke="Black"
StrokeThickness="1" Cursor="Hand"
MouseLeftButtonDown="StopClicked">
次に、上のコードで指定した関数をJavaScriptに追加します。この関数はどのストーリーボードが動いているのかを知る必要があります。そこで、ストーリーボードを起動したときその情報を保存しておくようにしましょう。次に示すように、 var storyboardObj = null; function stringPlucked(sender, args) { storyboardObj = sender.findName(sender.Name + "Indicatoranimation"); storyboardObj.begin(); } function StopClicked(sender, args) { if(storyboardObj != null) { //stop any animation first storyboardObj.stop(); } } XAMLとJSファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。そして、一番上の弦をクリックします。緑のインジケータが点滅します。次に、赤い停止ボタンをクリックすると、アニメーションが止まるはずです。他の5本の弦についても、同じようにコードを追加します。インジケータとストーリーボード要素の名前やそのインジケータ要素に対する これで第2の目標は完成です。 第3の目標次は第3の目標です。インジケータが表示されたら該当する弦の音を鳴らし、インジケータが消えたら音を止めなければなりません。 これには、それぞれの弦に対応する音程のサウンドファイルが必要です。この記事の冒頭で示したサンプルファイル(media.zipファイル)をダウンロードして展開します。その中にWMAファイルがあるので、それを他のファイルと同じ場所に移します。ファイルの名前は、XAMLファイル内の弦要素の名前に拡張子.wmaを付けたものになっているはずです。 XAMLはメディア要素を扱うこともできます。そこで、XAMLファイルを開き、次の要素を追加します。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <MediaElement x:Name="sound" Width="0" Height="0"/> <Ellipse Height="100" Width="100" Canvas.Left="30" Canvas.Top="25" Fill="Black"/> 名前が付けてあるのは、JavaScriptから指定できるようにするためです。このメディアは見せる必要がありませんから、高さと幅は0にします(必要なのは音だけです)。弦が弾かれるまではどの弦の音を出すかわからないので、ここではメディアファイルを指定しません。第3の目標は、アニメーションと同時にメディアを再生し、アニメーションの停止と同時にメディアの再生を止めることです。そこで、JavaScriptコードを次のように変更します。 function stringPlucked(sender, args) { storyboardObj = sender.findName(sender.Name + "Indicatoranimation"); storyboardObj.begin(); sender.findName("sound").Source = sender.Name + ".wma"; sender.findName("sound").Play(); } function StopClicked(sender, args) { if(storyboardObj != null) { //stop any animation first storyboardObj.stop(); sender.findName("sound").Stop(); } } このコードは、サウンド要素を探し出し、その function stringPlucked(sender, args) { StopClicked(sender,args); storyboardObj = sender.findName(sender.Name + "Indicatoranimation"); storyboardObj.begin(); sender.findName("sound").Source = sender.Name + ".wma"; sender.findName("sound").Play(); } XAMLファイルとJSファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。そして、一番上の弦をクリックすると、緑のインジケータが点滅し、スピーカーかヘッドフォンに音が聞こえるはずです。赤い停止ボタンをクリックするとアニメーションとサウンドは止まり、他の弦をクリックするとその弦の音が再生されるはずです。 うまく動いていますね。しかし、これでは実用上不便なところがあります。調弦は、普通、音を鳴らしながら行うからです。つまり、音がすぐに止まってしまうのでは使いにくいのです。長いサウンドファイルを使えば音は長くなりますが、これはメディアの無駄というのものです。メディアを反復して再生すればいいのですから。反復再生は、Storyboardアニメーションをちょっと工夫して実現することもできますが、ここでは別の方法を使ってみましょう。MediaElementはMediaEndedというイベントを発生させますから、このイベントを捕捉し、そのハンドラの中でメディアの頭からもう一度再生させるのです。次のように変更します。 XAMLファイル
<MediaElement x:Name="sound" Width="0" Height="0"
MediaEnded="endofmedia"/>
JavaScriptファイル
function endofmedia(sender,args) { //reached end, seek to beginning and play again var mediaElement = sender.findName("sound"); var position = mediaElement.position; position.seconds = 0; mediaElement.position = position; mediaElement.Play(); } XAMLファイルとJSファイルを保存し、ブラウザのHTMLファイルを再度読み込んでください。そして弦をクリックすると、緑のインジケータが点滅し、スピーカーかヘッドフォンに音が鳴り続け、停止ボタンをクリックすると止まるはずです。 以上で、ブラウザ上で動く簡単なギターチューナーが完成しました。 Vistaガジェットへの変換最後にVistaガジェットに変換するのですが、この作業は今までで最も簡単です。同じフォルダに「Gadget.xml」という名のファイルを作ってメモ帳で開き、次のコードを貼り付けます。 <?xml version="1.0" encoding="utf-8" ?> <gadget> <name>Guitar Tuner</name> <namespace>GuitarTuner</namespace> <version>1.0</version> <author name="[Your Name here]"> </author> <copyright>2007</copyright> <description>Guitar Tuner for tuning by ear</description> <icons> </icons> <hosts> <host name="sidebar"> <base type="HTML" apiVersion="1.0.0" src="GuitarTuner.html" /> <permissions>full</permissions> <platform minPlatformVersion="0.3" /> </host> </hosts> </gadget> 「名前を付けて保存」で保存し、エンコーディング方式としてUTF-8を選択します。これは重要です。こうしないと、正しいガジェットとして認識されません。ガジェットへの変換作業はこれで終わりです。ブラウザを管理しそこでガジェットを動かすというのが、ガジェットのフレームワークだからです。HTMLページで動けば、ガジェットの中でも十分動くのです。 ここで必要な作業は、ガジェット開発ガイドラインに準拠させ、外観を整え、正常に動作させることだけです。まず、「Vista gadget UI guidelines」に目を通します。 ガイドラインの中で、次の4点については既に準拠しているはずです。
したがって、問題はガジェットを格納したときの大きさを小さくすることだけです。そこで、次のように、GuitarTuner.HTMLでボディー要素の大きさを指定します。 <head> <title>Guitar Tuner</title> <style> body { width: 130px; height: 130px; margin: 0px; font-size:11px; font:10px segoe ui,tahoma; } </style> <script type="text/javascript" src="Silverlight.js"></script> <script type="text/javascript" src="guitartuner.js"></script> </head> これで、ガジェットのガイドラインに準拠できました。 Vistaでガジェットを使っている方ならご存じでしょうが、ガジェットはサイドバーに格納した状態でもサイドバーから出した状態でも使うことができます。Microsoftのガイドラインでは、格納したガジェットの大きさとして130ピクセル×130ピクセル、出したときの大きさは少し制限が緩くなり400ピクセル×400ピクセルが推奨されています。 130ピクセル×130ピクセルというのはかなり窮屈です。この大きさでは6本の弦を入れるのが精一杯です。しかし、400ピクセル×400ピクセルの矩形では、もう少し工夫ができます。ガジェットの開発者に推奨されていることの1つに見栄えのよさがあります。そこで、サイドバーから出ているときはギターのボディーを曲線的な形にしてみましょう。 それでは、サイドバーに格納されているのかサイドバーの外にあるのかをどのようにすれば知ることができるでしょうか。実は、ハンドラを登録するだけでこれらのイベントを捕捉できる機能が、VistaガジェットAPIに用意されています。イベントの通知を登録し、ハンドラの中で必要な処理を行います。つまり、ボディーがロードされたときにこれらのハンドラを登録し、そのハンドラの中で格納状態に応じてボディーの大きさを130から400に変更するのです。そのコードは下に示したようになりますが、説明は不要でしょう。 「GuitarTuner.HTML」を、次のように変更します。 <script type="text/javascript" src="guitartuner.js"></script> </head> <script type="text/javascript"> function loadMain() { //register for the events and pass in our handler System.Gadget.onDock = dockStateChanged; System.Gadget.onUndock = dockStateChanged; } function dockStateChanged() { //change size depending on state if(System.Gadget.docked) { document.body.style.width = "130px"; document.body.style.height = "130px"; } else { document.body.style.width = "400px"; document.body.style.height = "290px"; } } </script> <body onload="loadMain()"> <div id="SilverLightControlHost"> これで、ガジェットをサイドバーから出すと大きくなります。次に、このガジェット用にギターのボディーを作る必要があります。ここでは、背景画像を利用することにしましょう。サンプルの「media.zip」ファイルには、背景画像「BKGND.png」が含まれています。そこで、HTMLのスタイルを次のように変更します。
<style>
body
{
width: 130px;
height: 130px;
margin: 0px;
font-size:11px;
font:10px segoe ui,tahoma;
background-image:url(bkgnd.png);background-repeat:no-repeat;
}
</style>
そして、「guitarTuner.js」ファイルを開き、次のように背景色を白に変更します。 inplaceInstallPrompt:false, // Determines whether to display // in-place install prompt if // invalid version detected. background:'#00000000', // Background color of plugin. isWindowless:'true', // Determines whether to display plugin この時点でHTMLを起動すると、次のようになるはずです。 ![]() 位置がずれてしまいました。背景画像を少し左上にずらす必要があります。そこで、ボディーのスタイルを次のように調整します。 background-image:url(bkgnd.png); background-position: -80px -70px; background-repeat:none; このように変更すると別の問題が発生します。格納状態では確かに背景画像をこのように移動する必要があり、こうすれば弦などの要素はボディーに対して正しい位置になります。 一方、サイドバーから出した状態では、逆に、背景画像の左上をボディーの左上に合わせなければなりません。つまり、背景画像の位置を(0, 0)にする必要があるのです。しかし、背景画像は移動させたのですから、この場合は弦などの要素の方を移動しなければなりません。すべての要素を移動するのは大変なことです。簡単な方法はないのでしょうか。もちろんあります。キャンバスについて説明したことを思い出してください。キャンバスを別のキャンバスに含めることができるとお話ししましたね。これを利用するのです。すべての要素を1つのキャンバスに入れ、そのキャンバスをルートキャンバスの中に入れれば、子キャンバスを動かすだけでそこに含まれているすべての要素が自動的に動きます。 次に示すコードは、この方法を組み込んだものです。 <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/ presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Height="400" Width="290" > <Canvas x:Name="MainDrawing" Canvas.Left="0" Canvas.Top="0" Height="130" Width="130" > <MediaElement x:Name="sound" Width="0" Height="0" MediaEnded="endofmedia"/> ..... </Canvas> </Canvas> 次に、dockstatechangedハンドラの中で、これらの要素を動かします。 GuitarTuner.HTML
function dockStateChanged() { if(System.Gadget.docked) { document.body.style.width = "130px"; document.body.style.height = "130px"; document.body.style.backgroundPosition = "-80px -70px"; document.getElementById("guitarTunerControl").content. findName("MainDrawing")["Canvas.Left"]="0"; document.getElementById("guitarTunerControl").content. findName("MainDrawing")["Canvas.Top"]="-10"; } else { document.body.style.width = "400px"; document.body.style.height = "290px"; document.body.style.backgroundPosition = "0px 0px"; document.getElementById("guitarTunerControl").content. findName("MainDrawing")["Canvas.Left"]="80"; document.getElementById("guitarTunerControl").content. findName("MainDrawing")["Canvas.Top"]="70"; } } </script> これで完成です。あとはこのガジェットをインストールするだけです。次の方法が最も簡単でしょう。まず、フォルダにあるファイルをすべて(media.zipファイルを除く)選択し(Ctrl+Aを押します)、右クリックして[送る]→[圧縮(zip形式)フォルダ]を選択し、GuitarTunerフォルダのコンテンツを圧縮します(コンテンツだけを圧縮します。フォルダ自体を圧縮しないでください)。そして、そのzipファイルの拡張子を変更し、たとえば「GuitarTuner.gadget」とします。次に、Vistaマシン上で「GuitarTuner.gadget」ファイルをダブルクリックします。確認メッセージに応答すると、ガジェットが表示され使えるようになるはずです。格納されているガジェットをサイドバーから出してみてください。いかがですか? 参考資料著者紹介kirants(kirants)
|