(download sample source code)
ちまちま書いてきましたが、もう少しSilverlightらしいことを、ということで、次は、アニメーションとメディアを利用したサンプルです。
リストから選択した動画を再生して、半透明で回転させます。
さすがにちょっと長くなりますが、そんなに複雑じゃありません。
<UserControl xmlns="http://schemas.microsoft.com/client/2007" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="System.Windows.Controls.UserControl" x:Name="JSSample5"> <StackPanel Orientation="Vertical" > <ListBox x:Name="list_movie"> <ListBoxItem Content="SPIDER" /> <ListBoxItem Content="CAR" /> <ListBoxItem Content="5cm" /> </ListBox> <MediaElement x:Name="video" Source="" Width="0" Height="0"/> <StackPanel Orientation="Horizontal"> <StackPanel.Background> <ImageBrush ImageSource="http://silverlight.net/Themes/silverlight/images/logo.jpg"/> </StackPanel.Background> <Rectangle Width="320" Height="240"> <Rectangle.Fill> <VideoBrush SourceName="video" /> </Rectangle.Fill> </Rectangle> <TextBlock Text="転" FontSize="180" FontWeight="Bold" TextWrapping="Wrap" Opacity="0.5"> <TextBlock.RenderTransform> <RotateTransform x:Name="rotater" Angle="30" CenterX="120" CenterY="120" /> </TextBlock.RenderTransform> <TextBlock.Foreground> <VideoBrush SourceName="video" /> </TextBlock.Foreground> </TextBlock> </StackPanel> <StackPanel.Triggers> <EventTrigger RoutedEvent="StackPanel.Loaded"> <BeginStoryboard> <Storyboard x:Name="myStoryboard"> <DoubleAnimation Storyboard.TargetName="rotater" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:50" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger> </StackPanel.Triggers> </StackPanel> </UserControl>
Import("System.Windows.Application") Import("System.Windows.Controls") Import("System.Windows.Controls.UserControl") Import("System") function App() { this.scene = Application.Current.LoadRootVisual(new UserControl(), "app.xaml") } App.prototype = { start:function() { this.scene.list_movie.SelectionChanged += function (s,e){ var url = app.movies[s.SelectedItem.Content]; s.Parent.video.Source = new System.Uri(url); } }, movies:{ "SPIDER":"http://www.sonypictures.com/movies/spiderman2/video/sm2_teaser_high.asx", "CAR":"http://www.disney.co.jp/movies/cars/yokoku/media/eng_300k.wmv", "5cm":"http://rd.yahoo.co.jp/tokushu/5cm/teaser01/?http://i.yimg.jp/images/evt/5cm/teaser8000k1280_720.wmv" } } app = new App; app.start();
動画のリンク先がちょっとアレですが、サンプルってことで許してください。
flvが使えないのがSilverlightの辛いところ...。
まずは、新しい要素のListBoxですが、
<ListBox x:Name="list_movie"> <ListBoxItem Content="SPIDER" /> <ListBoxItem Content="CAR" /> <ListBoxItem Content="5cm" /> </ListBox>
これは、まぁ見たままです。
ListBoxコントロールにListBoxItemコントロールを子要素として持たせています。
ちなみに、このアイテムの追加部分は、JS側で、
var arr = ['SPIDER','CARS','5cm']; this.scene.list_movie.ItemsSource = arr;
などと処理することもできます。(+イベントハンドラに若干修正が必要)
次に、
<MediaElement x:Name="video" Source="" Width="0" Height="0"/>
このMediaElementは、ビデオ再生に利用しています。
ここでは、さらにこの動画を別の要素に張り込むため、サイズが0x0pxの不可視コントロールであるローダーとしてのみ使用。
実際の動画アドレスの設定はコード側でSourceプロパティに対して行っています。
そして、ここで「video」として定義したMediaElementを参照しているのが、
<Rectangle Width="320" Height="240"> <Rectangle.Fill> <VideoBrush SourceName="video" /> </Rectangle.Fill> </Rectangle>
こちらのRectangleコントロール。
塗りつぶし要素として<VideoBrush>を使用し、videoを参照しています。
もう一つの、TextBlockはもう少し複雑です。
<TextBlock Text="転" FontSize="180" FontWeight="Bold" TextWrapping="Wrap" Opacity="0.5"> <TextBlock.RenderTransform> <RotateTransform x:Name="rotater" Angle="30" CenterX="120" CenterY="120" /> </TextBlock.RenderTransform> <TextBlock.Foreground> <VideoBrush SourceName="video" /> </TextBlock.Foreground> </TextBlock>
基本的には「転」と書かれたTextBlockですが、ここでTransform(変形)オブジェクトを用いて、<TextBlock.RenderTransform>と<RotateTransform>を使うことでとりあえず30度回転させ、 <TextBlock.Foreground>で、前面の塗りつぶしとして、同じくvideoを参照しています。
<RotateTransform>は次のアニメーション用ストーリーボードで値を変更するために「rotater」と命名してあります。
最後に、StackPanelにアニメーション動作の引き金となるトリガとその実体を追加しています。
<StackPanel.Triggers> <EventTrigger RoutedEvent="StackPanel.Loaded"> <BeginStoryboard> <Storyboard x:Name="myStoryboard"> <DoubleAnimation Storyboard.TargetName="rotater" Storyboard.TargetProperty="Angle" From="0" To="360" Duration="0:0:50" RepeatBehavior="Forever" /> </Storyboard> </BeginStoryboard> </EventTrigger> </StackPanel.Triggers>
- 「StackPanelがロードされたら」
- 「rotaterのAngleプロパティを」
- 「0~360°まで」
- 「50秒間で」
- 「double値のアニメーションを行うストーリーボードを実行せよ」
というトリガが定義されています。
このようにアニメーションをXAML側で定義できてしまうため、さまざまな動的デザイン要素をプログラマではなくデザイナが定義することが可能になるわけです。
ここでは、XAMLを手書きしていますが、Expression Blendなどのデザインツールを使用すれば、FlashライクにGUIでタイムテーブルを編集してストーリーボードを作成することでアニメーションを定義できます。
また、Expression Blendでの編集結果をその場でXAMLとして堪忍できる点がSilverlightやWPFの面白いポイントだと言えるでしょう。
タグで見ていると頭がワヤになりますが、Blendを使って図形をぐりぐり動かしつつ出力されたXAMLをチェックしてみることで、Silverlightを使ってどのようなアニメーションが実現できるかを探ることができると思います。
以上、駆け足ですが、Silverlightの環境構築から、基本的なXAMLの書き方などSilverlightアプリ作成の基礎をまとめてみました。
Windowsやクライアントアプリにこれまで全く縁がない方々でも、基本的な部分さえわかってしまえば、Javascript、Python、Rubyなどの言語を利用することができ、なおかつ(今のところ)ブラウザ間の互換性をほとんど意識する必要もなく、比較的多くの環境で動作するリッチアプリケーションを作ることができる点がSilverlight2の一つのポイントだと思います。
Silverlight2による開発は、ほぼどんな環境でも利用可能で、ライセンスも不要、というわけで手軽に始めることができますので、このエントリーが興味を持っていただくきっかけになれば幸いです。