热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> Silverlight>>正文内容

Silverlight 模拟Nano5 界面效果【附示例代码下载】

发布时间:2010年05月06日点击数: 佚名

 前一阵无意中发现将iPod Nano5 横置后会出现一个动态的选歌界面(如下图示),感觉不错于是想用Silverlight来实现一下这个效果,欢迎大家拍砖。【示例代码下载

 

本来是放Demo演示,可是这个程序怎么也显示不出来,只好用图片了(感兴趣的话可以下载源代码):

 

       在制作过程中比较繁琐的部分是倒影效果,最开始的做法是将同一张专辑图片使用两次:一个作为专辑封面;一个作为倒影效果。对倒影效果图片进行RenderTransform->ScaleY 反转和OpacityMask->LinearGradientBrush 渐变处理,这样操作后出现一个问题:未选中专辑的封面和倒影之间有间隙(如下图示)。这是由于分别对封面和倒影进行PlaneProjection->RotationY 三维旋转时会使它们按各自的坐标轴进行旋转,不是以一个整体进行旋转而差生了偏差。如果将两个图片组合为一个StackPanel 或Canvas 然后再进行旋转感觉应该可以(但需要不少代码实现,效率可能会降低,感兴趣的朋友可以测试一下),最后偷懒用PS 给图片做了倒影~

 

 下面先来看看XAML,这部分就是为Canvas 增加一些事件:

  1. <Canvas x:Name="LayoutRoot" MouseLeftButtonDown="LayoutRoot_MouseLeftButtonDown"> 
  2. </Canvas> 

 

C# 内容请看注释详解:

  1. public partial class MainPage : UserControl 
  2.     private String[] ALBUMS = { "images/ep1.png""images/ep2.png""images/ep3.png",  
  3.                                 "images/ep4.png""images/ep5.png""images/ep6.png",  
  4.                                 "images/ep7.png""images/ep8.png""images/ep9.png" }; 
  5.     //当前位置 
  6.     private double CURRENT = 0; 
  7.     //目标位置 
  8.     private double TARGET = 0; 
  9.     //存储图片 
  10.     private List<Image> IMAGE = new List<Image>(); 
  11.     //计时器 
  12.     private DispatcherTimer TIMER = new DispatcherTimer(); 
  13.  
  14.     public MainPage() 
  15.     { 
  16.        InitializeComponent(); 
  17.        //加载图片 
  18.        addImages(); 
  19.        //对于不同浏览器加载滚轮事件 
  20.        HtmlPage.Window.AttachEvent("DOMMouseScroll", LayoutRoot_MouseWheel); 
  21.        HtmlPage.Window.AttachEvent("onmousewheel", LayoutRoot_MouseWheel); 
  22.        HtmlPage.Document.AttachEvent("onmousewheel", LayoutRoot_MouseWheel); 
  23.     } 
  24.  
  25.     private void addImages() 
  26.     { 
  27.         for (int i = 0; i < ALBUMS.Length; i++) 
  28.         { 
  29.            //逐一加载图片 
  30.            string url = ALBUMS[i]; 
  31.            Image cover = new Image(); 
  32.            cover.Source = new BitmapImage(new Uri(url, UriKind.Relative)); 
  33.            LayoutRoot.Children.Add(cover); 
  34.            //调整图片显示方式 
  35.            setImage(cover, i); 
  36.            //将图片加入IMAGE,用于实现动态效果 
  37.            IMAGE.Add(cover); 
  38.         } 
  39.     } 
  40.  
  41.     private void setImage(Image image, int index) 
  42.     { 
  43.         //遍历图片与当前(CURRENT)位置关系 
  44.         double offset = index - CURRENT; 
  45.         //对图片进行三维旋转 
  46.         PlaneProjection planeProjection = new PlaneProjection(); 
  47.         planeProjection.RotationY = Math.Abs(offset) * 65 / (offset != 0 ? offset : 1); 
  48.         image.Projection = planeProjection; 
  49.          
  50.         double left; 
  51.         double top = 50; 
  52.         double center = Width / 2 - 100; 
  53.         double scale = 1; 
  54.  
  55.         if (index == CURRENT) 
  56.         { 
  57.             left = center; 
  58.             top = 40; 
  59.             scale = 1.15; 
  60.         } 
  61.         else if (index > CURRENT) 
  62.         { 
  63.             left = center + offset * 50 + 60; 
  64.         } 
  65.         else 
  66.         { 
  67.             left = center + offset * 50 - 40; 
  68.         } 
  69.         //对CURRENT图片进行缩放 
  70.         ScaleTransform scaleTransform = new ScaleTransform(); 
  71.         scaleTransform.ScaleX = scale; 
  72.         scaleTransform.ScaleY = scale; 
  73.         image.RenderTransform = scaleTransform; 
  74.         //调整遍历图片位置 
  75.         image.SetValue(Canvas.LeftProperty, left); 
  76.         image.SetValue(Canvas.TopProperty, top); 
  77.         image.SetValue(Canvas.ZIndexProperty, (int)(-Math.Abs(offset)) * 100); 
  78.     } 
  79.  
  80.      //点击鼠标左键正向移动图片 
  81.      private void LayoutRoot_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
  82.      { 
  83.         moveIndex(1); 
  84.      } 
  85.  
  86.     /* 
  87.     * 如果将下面事件加入Canvas的MouseWheel="LayoutRoot_MouseWheel"(XAML)中, 
  88.     * 页面加载后初始不能获取滚轮事件。 
  89.     */ 
  90.     //private void LayoutRoot_MouseWheel(object sender, MouseWheelEventArgs e) 
  91.     //{ 
  92.     //    double mouseDelta = 0; 
  93.     //    mouseDelta = Math.Sign(e.Delta); 
  94.     //    moveIndex((mouseDelta > 0) ? 1 : -1); 
  95.     //} 
  96.  
  97.     //通过HtmlPage加载鼠标滚动事件,详情可参考资料<4> 
  98.     private void LayoutRoot_MouseWheel(object sender, HtmlEventArgs args) 
  99.     { 
  100.         double mouseDelta = 0; 
  101.         ScriptObject e = args.EventObject; 
  102.         // Mozilla and Safari     
  103.         if (e.GetProperty("detail") != null
  104.         { 
  105.             mouseDelta = ((double)e.GetProperty("detail")); 
  106.         } 
  107.  
  108.         // IE and Opera    
  109.         else if (e.GetProperty("wheelDelta") != null
  110.             mouseDelta = ((double)e.GetProperty("wheelDelta")); 
  111.  
  112.         mouseDelta = Math.Sign(mouseDelta); 
  113.  
  114.         moveIndex((mouseDelta > 0) ? 1 : -1); 
  115.     } 
  116.  
  117.     private void moveIndex(int value) 
  118.     { 
  119.         //获取目标图片位置,并确保其在图片数量范围内 
  120.         TARGET += value; 
  121.         TARGET = Math.Max(0, TARGET); 
  122.         TARGET = Math.Min(IMAGE.Count - 1, TARGET); 
  123.     } 
  124.  
  125.     //计时器Tick,移动到目标图片 
  126.     private void timerTick(object sender, EventArgs e) 
  127.     { 
  128.         for (int i = 0; i < IMAGE.Count; i++) 
  129.         { 
  130.             Image image = IMAGE[i]; 
  131.             setImage(image, i); 
  132.         } 
  133.         CURRENT = TARGET; 
  134.     } 
  135.  
  136.     //启动计时器 
  137.     public void startShow() 
  138.     { 
  139.         TIMER = new DispatcherTimer(); 
  140.         TIMER.Interval = new TimeSpan(0, 0, 0, 0, 10); 
  141.         TIMER.Tick += new EventHandler(timerTick); 
  142.         TIMER.Start(); 
  143.     } 

本站热点业务

更多模板/案例展示

关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作