博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# WPF 低仿网易云音乐(PC)Banner动画控件
阅读量:6961 次
发布时间:2019-06-27

本文共 18971 字,大约阅读时间需要 63 分钟。

原文:

由于技术有限没能做到一模一样的动画,只是粗略地做了一下。动画有点生硬,还有就是没做出网易云音乐的立体感。代码非常简单粗暴,而且我也写有很多注释,这里就不多啰嗦了,直接贴代码。

算了,啰嗦几句。原理是这样的,在自定义用户控件内添加3个border(左、中、右,以下分别简称为:b1、b2、b3),对border进行缩放和移动动画。往右切换时b1放大平移到b2的位置,b2缩小平移到b3的位置,b3平移到b1的位置,动画结束后重新记录3个border的左、中、右位置,然后如此循环。一次滚动有三个动画,分别写了3个方法来定义。

可加上透明动画、阴影,应该会更加好看些。

没有实现调用的方法,只是个纯动画项目,图片也是写死在前台代码中,需要在项目中使用时自行简单地修改即可。

 

低仿效果

网易云音乐原版

 

代码

后台

using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Text;using System.Threading.Tasks;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Animation;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;using System.Windows.Threading;namespace 网易云音乐Banner动画.Controls{    ///     /// CloudMusicBanner.xaml 的交互逻辑    ///     public partial class CloudMusicBanner : UserControl    {        //代码所用涉及时间单位均是:秒        #region 一些变量        //左、中、右三张banner的位置        double leftlocation = 0, centerlocation = 0, rightlocation = 0;        //每张banner的动画执行时间        double AnimationTime = 0.4;        //非中间banner的遮盖层透明度        double bopacity = 0.65;        //没有交互时动画自动执行间隔时间        double timeranimation_time = 4;        //动画播放状态(当前动画是否在执行)        bool isplay = false;        //三个banner border变量,用于暂时保存        Border b_left, b_center, b_right;        //通用缓动函数,提升动画流畅感        EasingFunctionBase easeFunction;        //banner集合,用于定位和记录border的位置(左,中,右)        Dictionary
Banners = new Dictionary
(); DispatcherTimer timeranimation; #endregion public CloudMusicBanner() { InitializeComponent(); //将三张banner(border)添加到banner集合 Banners.Add(Location.Left, left); Banners.Add(Location.Center, center); Banners.Add(Location.Right, right); //控件加载完成后 Loaded += (e, c) => { //首次启动设置三张banner的位置、大小信息 SetLocation(Location.Left, left); SetLocation(Location.Center, center); SetLocation(Location.Right, right); //启动定时器,用于自动播放滚动动画 TimerAnimationStart(); }; //初始化缓动函数 //quadraticease的easeout mode是从快到慢 //参考了博客:http://www.cnblogs.com/xwlyun/archive/2012/09/11/2680579.html easeFunction = new QuadraticEase() { EasingMode = EasingMode.EaseOut }; //初始化定时器 timeranimation = new DispatcherTimer(); //设置定时器的间隔时间 timeranimation.Interval = TimeSpan.FromSeconds(timeranimation_time); } #region 交互事件 private void UserControl_MouseEnter(object sender, MouseEventArgs e) { //鼠标移入控件时显示两个“左/右”图标按钮 toleftbtn.Opacity = 1; } private void UserControl_MouseLeave(object sender, MouseEventArgs e) { //鼠标移出控件时隐藏两个“左/右”图标按钮 toleftbtn.Opacity = 0; } private void toleftbtn_Click(object sender, RoutedEventArgs e) { //向左图标按钮点击 LeftAnimation(); } private void torightbtn_Click(object sender, RoutedEventArgs e) { RightAnimation(); } #endregion //左切换动画时三张banner向右滚动 /* * 即中间的border移动至:右 * 右边的border移动至:左 * 左边的border移动至:中 */ #region 左切换动画 public void LeftAnimation() { //启动动画时停止定时器 timeranimation.Stop(); //设置动画播放状态为真 isplay = true; //启动相应的动画 LefttoCenterAnimation(); CentertoRightAnimation(); RighttoLeftAnimation(); } //【仅注释此方法,以下代码均大多重复故不再注释】 #region 左切换动画-中向右动画 public void CentertoRightAnimation() { //记录动画结束后的位置,即当动画结束后中间的BORDER移动到右变成了右,代码:Banners[Location.Right] = b_center; b_center = Banners[Location.Center]; //设置一下border的显示层级 Grid.SetZIndex(Banners[Location.Center], 2); //获取透明遮盖图层,设置透明度 /* *
* 透明遮盖图层在设计代码中的每个border内 * */ GetOpacityGrid(b_center).Opacity = bopacity; //定义一个缩放转换对象(用于banner从大到小的动画) ScaleTransform scale = new ScaleTransform(); //需要设置中心点y坐标为控件的高度,不设置的话border是靠在顶部执行动画的。 scale.CenterY = this.ActualHeight; //定义一个水平移动转换对象 TranslateTransform ts = new TranslateTransform(); //定义一个转换集合 TransformGroup group = new TransformGroup(); //将上面的缩放、平移转换对象添加到集合 group.Children.Add(scale); group.Children.Add(ts); //将转换集合赋予给中心banner Banners[Location.Center].RenderTransform = group; //定义一个缩放动画 DoubleAnimation scaleAnimation = new DoubleAnimation() { //从1(100%即默认比例) From = 1, //到0.95(95%即从默认比例缩小到95%的比例大小) To = 0.95, //设置缓动函数 EasingFunction = easeFunction, //动画执行所需时间 Duration = TimeSpan.FromSeconds(AnimationTime) }; //定义一个移动动画(用于banner从左到右.....移动动画等) DoubleAnimation moveAnimation = new DoubleAnimation() { //从中心banner位置 From = centerlocation, //移动到右banner位置 To = rightlocation, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; //启动缩放动画 scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation); scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); //启动平移动画 ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation); } #endregion #region 左切换动画-右向左动画 public void RighttoLeftAnimation() { b_right = Banners[Location.Right]; Grid.SetZIndex(Banners[Location.Right], 1); GetOpacityGrid(b_right).Opacity = bopacity; ScaleTransform scale = new ScaleTransform(); //缩放 scale.CenterY = this.ActualHeight; TranslateTransform ts = new TranslateTransform();//平移 TransformGroup group = new TransformGroup(); group.Children.Add(scale); group.Children.Add(ts); Banners[Location.Right].RenderTransform = group; DoubleAnimation scaleAnimation = new DoubleAnimation() { From = 0.85, To = 0.95, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; DoubleAnimation moveAnimation = new DoubleAnimation() { From = rightlocation, To = leftlocation, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; //scaleAnimation.Completed += new EventHandler(scaleAnimation_Completed); // AnimationClock clock = scaleAnimation.CreateClock(); scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation); scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); //启动平移动画 ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation); } #endregion #region 左切换动画-左向中动画 public void LefttoCenterAnimation() { b_left = Banners[Location.Left]; Grid.SetZIndex(Banners[Location.Left], 3); GetOpacityGrid(b_left).Opacity = 0; ScaleTransform scale = new ScaleTransform(); //缩放 //scale.CenterX = 0; scale.CenterY = this.ActualHeight; TranslateTransform ts = new TranslateTransform();//平移 TransformGroup group = new TransformGroup(); group.Children.Add(scale); group.Children.Add(ts); Banners[Location.Left].RenderTransform = group; DoubleAnimation scaleAnimation = new DoubleAnimation() { From = 0.95, To = 1, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; DoubleAnimation moveAnimation = new DoubleAnimation() { From = leftlocation, To = centerlocation, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; scaleAnimation.Completed += new EventHandler(LeftAnimation_Completed); // AnimationClock clock = scaleAnimation.CreateClock(); scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation); scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); //启动平移动画 ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation); } #endregion #region 动画结束 private void LeftAnimation_Completed(object sender, EventArgs e) { //动画结束后将banner集合的位置重新设置 Banners[Location.Left] = b_right; Banners[Location.Center] = b_left; Banners[Location.Right] = b_center; //此时动画结束 isplay = false; //启动定时器 TimerAnimationStart(); } #endregion #endregion #region 右切换动画 public void RightAnimation() { timeranimation.Stop(); isplay = true; LefttoRightAnimation(); CentertoLeftAnimation(); RighttoCenterAnimation(); } #region 右切换动画-左向右动画 public void LefttoRightAnimation() { b_left = Banners[Location.Left]; Grid.SetZIndex(Banners[Location.Left], 1); GetOpacityGrid(b_left).Opacity = bopacity; ScaleTransform scale = new ScaleTransform(); //缩放 scale.CenterY = this.ActualHeight; TranslateTransform ts = new TranslateTransform();//平移 TransformGroup group = new TransformGroup(); group.Children.Add(scale); group.Children.Add(ts); Banners[Location.Left].RenderTransform = group; DoubleAnimation scaleAnimation = new DoubleAnimation() { From = 0.85, To = 0.95, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; DoubleAnimation moveAnimation = new DoubleAnimation() { From = leftlocation, To = rightlocation, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation); scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); //启动平移动画 ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation); } #endregion #region 右切换动画-中向左动画 public void CentertoLeftAnimation() { b_center = Banners[Location.Center]; Grid.SetZIndex(Banners[Location.Center], 2); GetOpacityGrid(b_center).Opacity = bopacity; ScaleTransform scale = new ScaleTransform(); //缩放 scale.CenterY = this.ActualHeight; TranslateTransform ts = new TranslateTransform();//平移 TransformGroup group = new TransformGroup(); group.Children.Add(scale); group.Children.Add(ts); Banners[Location.Center].RenderTransform = group; DoubleAnimation scaleAnimation = new DoubleAnimation() { From = 1, To = 0.95, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; DoubleAnimation moveAnimation = new DoubleAnimation() { From = centerlocation, To = leftlocation, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; //scaleAnimation.Completed += new EventHandler(scaleAnimation_Completed); // AnimationClock clock = scaleAnimation.CreateClock(); scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation); scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); //启动平移动画 ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation); } #endregion #region 右切换动画-右向中动画 public void RighttoCenterAnimation() { b_right = Banners[Location.Right]; //SetZindex(b_right); Grid.SetZIndex(Banners[Location.Right], 3); GetOpacityGrid(b_right).Opacity = 0; ScaleTransform scale = new ScaleTransform(); //缩放 //scale.CenterX = 0; scale.CenterY = this.ActualHeight; TranslateTransform ts = new TranslateTransform();//平移 TransformGroup group = new TransformGroup(); group.Children.Add(scale); group.Children.Add(ts); Banners[Location.Right].RenderTransform = group; DoubleAnimation scaleAnimation = new DoubleAnimation() { To = 1, From = 0.95, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; DoubleAnimation moveAnimation = new DoubleAnimation() { From = rightlocation, To = centerlocation, EasingFunction = easeFunction, Duration = TimeSpan.FromSeconds(AnimationTime) }; scaleAnimation.Completed += new EventHandler(RightAnimation_Completed); // AnimationClock clock = scaleAnimation.CreateClock(); scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation); scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation); //启动平移动画 ts.BeginAnimation(TranslateTransform.XProperty, moveAnimation); } #endregion #region 动画结束 private void RightAnimation_Completed(object sender, EventArgs e) { Banners[Location.Left] = b_center; Banners[Location.Center] = b_right; Banners[Location.Right] = b_left; isplay = false; TimerAnimationStart(); } #endregion #endregion #region 初始化设置控件位置 //定义一个枚举类用于标识左中右三个banner(border),方便操作时获取到。 public enum Location { Left, Center, Right } //设置三个border的大小和位置 public void SetLocation(Location l, Border g) { //banner的大小 g.Width = 540; g.Height = 200; //给除中间banner外的border缩小一些 ScaleTransform scaleTransform = new ScaleTransform(); scaleTransform.ScaleX = 0.95; scaleTransform.ScaleY = 0.95; scaleTransform.CenterY = this.ActualHeight; //获取设置遮盖层的透明度 Grid opacity_grid = GetOpacityGrid(g); opacity_grid.Opacity = bopacity; switch (l) { case Location.Left: TranslateTransform tt_left = new TranslateTransform() { X = 0 }; TransformGroup group_left = new TransformGroup(); group_left.Children.Add(tt_left); group_left.Children.Add(scaleTransform); g.RenderTransform = group_left; break; case Location.Center: opacity_grid.Opacity = 0; TransformGroup group_center = new TransformGroup(); //计算中心banner的x位置 centerlocation = (this.ActualWidth - g.ActualWidth) / 2; TranslateTransform tt_center = new TranslateTransform() { X = centerlocation }; group_center.Children.Add(tt_center); g.RenderTransform = group_center; Grid.SetZIndex(g, 3); break; case Location.Right: //Grid.SetZIndex(g, 3); //计算右banner的X位置 rightlocation = (this.ActualWidth - Banners[Location.Left].ActualWidth * 0.95); TranslateTransform tt_right = new TranslateTransform() { X = rightlocation }; TransformGroup group_right = new TransformGroup(); //这里要注意先后顺序,否则位置会有偏差,必须先缩放再设置X坐标。 group_right.Children.Add(scaleTransform); group_right.Children.Add(tt_right); g.RenderTransform = group_right; break; } } #endregion //获取透明覆盖层 //代码来自:https://www.cnblogs.com/udoless/p/3381411.html #region 获取透明覆盖层 public Grid GetOpacityGrid(DependencyObject g) { Grid opacity_grid = GetChild
(g, typeof(Grid)); opacity_grid = GetChild
(opacity_grid, typeof(Grid)); return opacity_grid; } public T GetChild
(DependencyObject obj, Type typename) where T : FrameworkElement { DependencyObject child = null; List
childList = new List
(); for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++) { child = VisualTreeHelper.GetChild(obj, i); if (child is T && (((T)child).GetType() == typename)) { return ((T)child); } } return null; } #endregion #region 定时唤醒动画 public void TimerAnimationStart() { if (timeranimation.IsEnabled == false) { timeranimation.Start(); } timeranimation.Tick += (e, c) => { timeranimation.Stop(); if (isplay == false) { RightAnimation(); } }; } #endregion }}

前台

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

被你发现了

项目下载在这

你可能感兴趣的文章
Python 获取本机ip地址
查看>>
NO.1 关于禅道
查看>>
win-codeblocks-16.01
查看>>
资本主义系统的基本结构
查看>>
财务企业网银故障快速攻克
查看>>
谭浩强C语言下载
查看>>
我的友情链接
查看>>
weblogic 启动脚本
查看>>
lamp-配置防盗链、访问控制Directory(针对目录)、访问控制(针对单文件)
查看>>
Cacti中文版在Centos上的安装(1)
查看>>
转:路由器MTU值对于网络通讯的影响(解决部分网站打不开问题)
查看>>
状态模式
查看>>
PHP,安卓,ios相互适用的AES加密算法
查看>>
我的友情链接
查看>>
LitePal的使用
查看>>
查找旁站路径的几种方法
查看>>
Cisco路由配置入门
查看>>
图片数据&大文本数据存储
查看>>
我的友情链接
查看>>
创建并调用 DLL(1)
查看>>