Silverlight模拟Nano5界面效果 -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【meiwen.anslib.com - 电脑资料】

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

Silverlight模拟Nano5界面效果

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

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

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


C# 内容请看注释详解:

public partial class MainPage : UserControl
{
   private String[] ALBUMS = { "images/ep1.png", "images/ep2.png",  "images/ep3.png",
                 "images/ep4.png", "images/ep5.png", "images/ep6.png",
                 "images/ep7.png", "images/ep8.png", "images/ep9.png" };
   //当前位置
   private double CURRENT = 0;
   //目标位置
   private double TARGET = 0;
   //存储图片
   private List IMAGE = new List();
   //计时器
   private DispatcherTimer TIMER = new DispatcherTimer();

   public MainPage()
   {
     InitializeComponent();
     //加载图片
     addImages();
     //对于不同浏览器加载滚轮事件
     HtmlPage.Window.AttachEvent("DOMMouseScroll",  LayoutRoot_MouseWheel);
     HtmlPage.Window.AttachEvent("onmousewheel",  LayoutRoot_MouseWheel);
     HtmlPage.Document.AttachEvent("onmousewheel",  LayoutRoot_MouseWheel);
   }

   private void addImages()
   {
     for (int i = 0; i < ALBUMS.Length; i++)
     {
       //逐一加载图片
       string url = ALBUMS[i];
       Image cover = new Image();
       cover.Source = new BitmapImage(new Uri(url,  UriKind.Relative));
       LayoutRoot.Children.Add(cover);
       //调整图片显示方式
       setImage(cover, i);
       //将图片加入IMAGE,用于实现动态效果
       IMAGE.Add(cover);
     }
   }

   private void setImage(Image image, int index)
   {
     //遍历图片与当前(CURRENT)位置关系
     double ffset = index - CURRENT;
     //对图片进行三维旋转
     PlaneProjection planeProjection = new PlaneProjection();
     planeProjection.RotationY = Math.Abs(offset) * 65 / (offset !=  0 ? offset : 1);
     image.Projection = planeProjection;

     double left;
     double top = 50;
     double center = Width / 2 - 100;
     double scale = 1;

     if (index == CURRENT)
     {
       left = center;
       top = 40;
       scale = 1.15;
     }
     else if (index > CURRENT)
     {
       left = center + offset * 50 + 60;
     }
     else
     {
       left = center + offset * 50 - 40;
     }
     //对CURRENT图片进行缩放
     ScaleTransform. scaleTransform. = new ScaleTransform();
     scaleTransform.ScaleX = scale;
     scaleTransform.ScaleY = scale;
     image.RenderTransform. = scaleTransform;
     //调整遍历图片位置
     image.SetValue(Canvas.LeftProperty, left);
     image.SetValue(Canvas.TopProperty, top);
     image.SetValue(Canvas.ZIndexProperty, (int)(-Math.Abs(offset)) *  100);
   }

    //点击鼠标左键正向移动图片
    private void LayoutRoot_MouseLeftButtonDown(object sender,  MouseButtonEventArgs e)
    {
     moveIndex(1);
    }

   /*
   * 如果将下面事件加入Canvas的MouseWheel="LayoutRoot_MouseWheel"(XAML)中 ,
   * 页面加载后初始不能获取滚轮事件,

电脑资料

Silverlight模拟Nano5界面效果》(http://meiwen.anslib.com)。
   */
   //private void LayoutRoot_MouseWheel(object sender,  MouseWheelEventArgs e)
   //{
   //  double mouseDelta = 0;
   //  mouseDelta = Math.Sign(e.Delta);
   //  moveIndex((mouseDelta > 0) ? 1 : -1);
   //}

   //通过HtmlPage加载鼠标滚动事件,详情可参考资料<4>
   private void LayoutRoot_MouseWheel(object sender, HtmlEventArgs  args)
   {
     double mouseDelta = 0;
     ScriptObject e = args.EventObject;
     // Mozilla and Safari
     if (e.GetProperty("detail") != null)
     {
       mouseDelta = ((double)e.GetProperty("detail"));
     }

     // IE and Opera
     else if (e.GetProperty("wheelDelta") != null)
       mouseDelta = ((double)e.GetProperty("wheelDelta"));

     mouseDelta = Math.Sign(mouseDelta);

     moveIndex((mouseDelta > 0) ? 1 : -1);
   }

   private void moveIndex(int value)
   {
     //获取目标图片位置,并确保其在图片数量范围内
     TARGET += value;
     TARGET = Math.Max(0, TARGET);
     TARGET = Math.Min(IMAGE.Count - 1, TARGET);
   }

   //计时器Tick,移动到目标图片
   private void timerTick(object sender, EventArgs e)
   {
     for (int i = 0; i < IMAGE.Count; i++)
     {
       Image image = IMAGE[i];
       setImage(image, i);
     }
     CURRENT = TARGET;
   }

   //启动计时器
   public void startShow()
   {
     TIMER = new DispatcherTimer();
     TIMER.Interval = new TimeSpan(0, 0, 0, 0, 10);
     TIMER.Tick += new EventHandler(timerTick);
     TIMER.Start();
   }
}

至此,Nano5 的界面效果已完成,借此作品献给已世的 * MJ * 。

出处: http://www.cnblogs.com/gnielee/

最新文章