Silverlight 3 ShowCase(1)- 3D圖片走馬燈
前提條件:
閱讀本文之前請確認你已經(jīng)安裝了如下軟件
- Visual Studio 2008 (Express) SP1
- Silverlight 3 Tools For Visual Studio
- Microsoft Expression Blend 3 MIX 09 Preview
ShowCase一瞥:
本文的ShowCase是一個3D的圖片走馬燈程序
圖片的來源是來自Flickr圖片共享網(wǎng)站
大家可以通過搜索關(guān)鍵字來獲取得到8張圖片
在線Demo
效果圖
關(guān)鍵代碼:
本文的圖片來自Flickr,為了獲取得到圖片
我們需要了解下Flickr Service API
在這里采用flickr.photos.search這個接口來搜索并獲取圖片
于是我們就有了我們搜索的圖片的Rest Url了
private string SearchFormattedUrl = "http://api.flickr.com/services/rest/?method=flickr.photos.search
&api_key={0}&text={1}&safe_search=1&sort=relevance&per_page={2}&page={3}";
其中{0}用來輸入Flickr的APIKey(只有提供這個才能訪問Flickr的API)
{1}用來提供我們搜索的關(guān)鍵字
{2}用來提供每頁返回多少個結(jié)果
{3}用來提供搜索的是第幾頁
采用如下方法來返回結(jié)果
1: public FlickrGallery(string apiKey)
2: {
3: APIKey = apiKey;
4: }
5:
6: public void SearchPhotos(string query, uint per_page, uint page, Action<string, List<ImageInfo>> photosCallback)
7: {
8: Uri searchUri = new Uri(String.Format(SearchFormattedUrl, APIKey, query, per_page.ToString(), page.ToString()));
9: WebClient imageClient = new WebClient();
10: imageClient.DownloadStringAsync(searchUri);
11: imageClient.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e)
12: {
13: if ((e.Cancelled == false) && (e.Error == null))
14: {
15: try
16: {
17: string xmlStr = e.Result;
18: if (!String.IsNullOrEmpty(xmlStr))
19: {
20: XDocument doc = XDocument.Parse(xmlStr);
21: var imgs = from flickrImg in doc.Descendants("photo")
22: select new ImageInfo()
23: {
24: Title = (string)flickrImg.Attribute("title"),
25: ImageUrl = String.Format(ImageUrlFormat, flickrImg.Attribute("farm").Value, flickrImg.Attribute("server").Value, flickrImg.Attribute("id").Value, flickrImg.Attribute("secret").Value)
26: };
27: List<ImageInfo> images = imgs.ToList();
28:
29: photosCallback(query, images);
30: return;
31: }
32: }
33:
34: catch
35: {
36: photosCallback(query, null);
37: }
38: }
39:
40: else
41: {
42: photosCallback(query, null);
43: }
44: };
45: }
這里采用了LINQ語句來Parse獲取得到的XML文件
接下來就是在我們的主XMAL文件中獲取圖片信息了
1: private void SearchImagesInfo()
2: {
3: string query = SearchBox.Text.Trim();
4: if (query != String.Empty)
5: {
6: this.SearchingProgress.IsActive = true;
7: this.ImagePanel.Children.Clear();
8: photoGalley.SearchPhotos(query, 8, 1, OnPhotoGalleryPhotosSearched);
9: }
10: }
11:
12: private void OnPhotoGalleryPhotosSearched(string query, List<ImageInfo> photos)
13: {
14: this.SearchingProgress.IsActive = false;
15: foreach (ImageInfo photo in photos)
16: {
17: BitmapImage bitmap = new BitmapImage(new Uri(photo.ImageUrl, UriKind.Absolute));
18:
19: int index=photos.IndexOf(photo);
20:
21: AddTheImage(bitmap, index);
22: }
23: }
其中SearchingProgress是一個效果控件
用來指示當前是否還在下載圖片信息,其效果圖如下
通過其屬性IsActive來控制其是否可見
接下來就是將獲取得到的圖片添加到將用來放置圖片的面板上了
1: private void AddTheImage(ImageSource source,int index)
2: {
3: Image image = new Image()
4: {
5: Source = source
6: };
7:
8: image.Width = 200;
9: image.Height = 150;
10: image.HorizontalAlignment = HorizontalAlignment.Left;
11:
12: DropShadowEffect dsEff = new DropShadowEffect();
13: dsEff.ShadowDepth = 10;
14: dsEff.BlurRadius = 10;
15: dsEff.Color = Color.FromArgb(120, 60, 60, 60);
16:
17: image.Effect = dsEff;
18:
19: PlaneProjection projection = new PlaneProjection();
20: projection.LocalOffsetY = -index * 10;
21: projection.LocalOffsetX = index * 70;
22: projection.LocalOffsetZ = -index * 10;
23: image.Projection = projection;
24: image.MouseLeftButtonDown += new MouseButtonEventHandler(image_MouseLeftButtonDown);
25: this.ImagePanel.Children.Add(image);
26: }
在這里我對圖片加了DropShadowEffect特效
大家也可以通過自定義一個投影圖片來展示效果
此外這里使用了PlaneProjection來展示3D效果
我根據(jù)當前圖片的編號來3D安排這些圖片的位置(行19~23)
下面就是處理圖片被點擊的狀況下圖片的移動效果了
1: void image_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
2: {
3: Image clickedImage = sender as Image;
4:
5: List<UIElement> elems = this.ImagePanel.Children.ToList();
6: int clickedIndex = elems.IndexOf(clickedImage);
7:
8: if (clickedIndex != 0)
9: {
10: if (isAnimateCompleted)
11: MoveImages();
12: }
13: }
14:
15: private void MoveImages()
16: {
17: if (this.ImagePanel.Children.Count > 0)
18: {
19: isAnimateCompleted = false;
20: Image firstImage = this.ImagePanel.Children[0] as Image;
21: this.ImagePanel.Children.RemoveAt(0);
22: AddTheImage(firstImage.Source, 8);
23: Storyboard sb = new Storyboard();
24: for (int index = 0; index < this.ImagePanel.Children.Count; index++)
25: {
26: Image img = this.ImagePanel.Children[index] as Image;
27:
28: double seconds = 1.0 + index * 0.03;
29:
30: sb = AnimateStory(img, seconds, -70, 10, 10);
31: sb.Begin();
32: }
33:
34: sb.Completed += (sender, e) =>
35: {
36: isAnimateCompleted = true;
37: };
38: }
39: }
如果點擊的是第一張圖片,將不會產(chǎn)生移動
而移動的效果我們采用自定義一個移動的Storyboard來處理
1: private Storyboard AnimateStory(UIElement elem, double seconds, double deltaX, double deltaY, double deltaZ)
2: {
3: Storyboard sb = new Storyboard();
4:
5: DoubleAnimation dAnimX = new DoubleAnimation();
6: dAnimX.By = deltaX;
7: dAnimX.Duration = new Duration(TimeSpan.FromSeconds(seconds));
8: Storyboard.SetTargetProperty(dAnimX, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetX)"));
9: Storyboard.SetTarget(dAnimX, elem);
10:
11: DoubleAnimation dAnimY = new DoubleAnimation();
12: dAnimY.By = deltaY;
13: dAnimY.Duration = new Duration(TimeSpan.FromSeconds(1));
14: Storyboard.SetTargetProperty(dAnimY, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetY)"));
15: Storyboard.SetTarget(dAnimY, elem);
16:
17: DoubleAnimation dAnimZ = new DoubleAnimation();
18: dAnimZ.By = deltaZ;
19: dAnimZ.Duration = new Duration(TimeSpan.FromSeconds(1));
20: Storyboard.SetTargetProperty(dAnimZ, new PropertyPath("(UIElement.Projection).(PlaneProjection.LocalOffsetZ)"));
21: Storyboard.SetTarget(dAnimZ, elem);
22:
23: sb.Children.Add(dAnimX);
24: sb.Children.Add(dAnimY);
25: sb.Children.Add(dAnimZ);
26:
27: return sb;
28: }
Storyboard雖然可以使用Blend很好的獲得,但是采用編程的方式會更加好控制以及好重用
這里我采用了每個圖片的動畫的時間不同來制造一種良好的時間差效果來增強用戶體驗度
double seconds = 1.0 + index * 0.03;
sb = AnimateStory(img, seconds, -70, 10, 10);
private IPhotoGallery photoGalley;
public MainPage(string apiKey)
{
InitializeComponent();
photoGalley = new FlickrGallery(apiKey);
this.KeyDown+=(sender,e)=>
{
switch (e.Key)
{
case Key.Enter: SearchImagesInfo(); break;
case Key.Right: if (isAnimateCompleted) { MoveImages(); } break;
}
};
}
<asp:Silverlight ID="SL" runat="server" Source="~/ClientBin/FlickrBrowser.xap" InitParameters="FlickrKey=539ddb5257617b1c7045c4539df97337"
MinimumVersion="3.0.40307.0" Width="100%" Height="100%" />
接下來就可以在App.xaml.cs文件中Parse出初始化的參數(shù),并傳遞給MainPage
private void Application_Startup(object sender, StartupEventArgs e)
{
string flickrKey = "";
if (e.InitParams.ContainsKey("FlickrKey"))
{
flickrKey = e.InitParams["FlickrKey"];
}
this.RootVisual = new MainPage(flickrKey);
}
代碼下載:
出處:http://ibillguo.cnblogs.com/
本文版權(quán)由作者和博客園共同所有,轉(zhuǎn)載請注明出處

浙公網(wǎng)安備 33010602011771號