第一次进入以然胜甲的EaranSE系统觉得首页上的动画效果蛮帅的,所以自己就抽时间研究了一下如何实现的。
先分析一下页面状态
页面状态(默认)1:
![](http://bbs.silverlightchina.net/data/attachment/album/201011/17/153011zvq7td0txmjt7mxj.jpg)
页面状态(Button点击后)2:
![](http://bbs.silverlightchina.net/data/attachment/album/201011/17/153013dcxdy6omcmzmcyxt.jpg)
页面状态(Button位置互换)3:
![](http://bbs.silverlightchina.net/data/attachment/album/201011/17/153018mafsmk079um2kxml.jpg)
页面状态(Buuton还原到默认情况)4:
![](http://bbs.silverlightchina.net/data/attachment/album/201011/17/153011zvq7td0txmjt7mxj.jpg)
下边我们以Grid Width="910" Height="490" 二行三列的Button 利用Canvas 为例子来实现
XAML代码:
<Grid x:Name="LayoutRoot" Background="White" Width="910" Height="490">
<Canvas>
<!--第一行-->
<Button x:Name="btnNum1" Height="240" Width="300" Content="Button1" RenderTransformOrigin="0,0" Canvas.Top="2" Canvas.Left="2" Click="btnNum_Click"></Button>
<Button x:Name="btnNum2" Height="240" Width="300" Content="Button2" RenderTransformOrigin="0,0" Canvas.Top="2" Canvas.Left="305" Click="btnNum_Click"></Button>
<Button x:Name="btnNum3" Height="240" Width="300" Content="Button3" RenderTransformOrigin="0,0" Canvas.Top="2" Canvas.Left="608" Click="btnNum_Click"></Button>
<!--第二行-->
<Button x:Name="btnNum4" Height="240" Width="300" Content="Button4" RenderTransformOrigin="0,0" Canvas.Top="248" Canvas.Left="2" Click="btnNum_Click"></Button>
<Button x:Name="btnNum5" Height="240" Width="300" Content="Button5" RenderTransformOrigin="0,0" Canvas.Top="248" Canvas.Left="305" Click="btnNum_Click"></Button>
<Button x:Name="btnNum6" Height="240" Width="300" Content="Button6" RenderTransformOrigin="0,0" Canvas.Top="248" Canvas.Left="608" Click="btnNum_Click"></Button>
</Canvas>
</Grid>
<Canvas>
<!--第一行-->
<Button x:Name="btnNum1" Height="240" Width="300" Content="Button1" RenderTransformOrigin="0,0" Canvas.Top="2" Canvas.Left="2" Click="btnNum_Click"></Button>
<Button x:Name="btnNum2" Height="240" Width="300" Content="Button2" RenderTransformOrigin="0,0" Canvas.Top="2" Canvas.Left="305" Click="btnNum_Click"></Button>
<Button x:Name="btnNum3" Height="240" Width="300" Content="Button3" RenderTransformOrigin="0,0" Canvas.Top="2" Canvas.Left="608" Click="btnNum_Click"></Button>
<!--第二行-->
<Button x:Name="btnNum4" Height="240" Width="300" Content="Button4" RenderTransformOrigin="0,0" Canvas.Top="248" Canvas.Left="2" Click="btnNum_Click"></Button>
<Button x:Name="btnNum5" Height="240" Width="300" Content="Button5" RenderTransformOrigin="0,0" Canvas.Top="248" Canvas.Left="305" Click="btnNum_Click"></Button>
<Button x:Name="btnNum6" Height="240" Width="300" Content="Button6" RenderTransformOrigin="0,0" Canvas.Top="248" Canvas.Left="608" Click="btnNum_Click"></Button>
</Canvas>
</Grid>
Button 的高度和宽度设置为:Height="240" Width="300" 910的宽度 3个Button 刚好900还剩下10作为了Button之间的间距,高度也是同理。
c#
页面状态1:
private string clickName = string.Empty;//记录单击控件名称 2、3、4状态用
private List<double> Tops = new List<double>();//Top位置坐标
private List<Button> Buttons = new List<Button>();//Button集
private List<Button> Buttons = new List<Button>();//Button集
public Default()
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
//95:初始化后控件高 3:间距
Tops.Add(i * 95 + 5);
}
Buttons.Add(btnNum1);
Buttons.Add(btnNum2);
Buttons.Add(btnNum3);
Buttons.Add(btnNum4);
Buttons.Add(btnNum5);
Buttons.Add(btnNum6);
}
{
InitializeComponent();
for (int i = 0; i < 5; i++)
{
//95:初始化后控件高 3:间距
Tops.Add(i * 95 + 5);
}
Buttons.Add(btnNum1);
Buttons.Add(btnNum2);
Buttons.Add(btnNum3);
Buttons.Add(btnNum4);
Buttons.Add(btnNum5);
Buttons.Add(btnNum6);
}
接下来我们来实现 页面状态2:
添加Button事件
private void btnNum_Click(object sender, RoutedEventArgs e)
{
Button btnClick = sender as Button;
//判断执行动画
if (string.IsNullOrEmpty(clickName) == true)//初始化动画
{
clickName = btnClick.Name;
Initialization();
}
}
{
Button btnClick = sender as Button;
//判断执行动画
if (string.IsNullOrEmpty(clickName) == true)//初始化动画
{
clickName = btnClick.Name;
Initialization();
}
}
private void Initialization()
{
Storyboard sb = new Storyboard();
int iTop = 0;
for (int i = 0; i < 6; i++)
{
Button btn = Buttons[i];
if (btn.Name == clickName)//判断是否是单击对象
{
MaxButton(sb, btn);
}
else
{
ReduceButton(sb, btn, 200, 95, Tops[iTop], 710);
iTop++;
}
}
sb.Begin();
}
{
Storyboard sb = new Storyboard();
int iTop = 0;
for (int i = 0; i < 6; i++)
{
Button btn = Buttons[i];
if (btn.Name == clickName)//判断是否是单击对象
{
MaxButton(sb, btn);
}
else
{
ReduceButton(sb, btn, 200, 95, Tops[iTop], 710);
iTop++;
}
}
sb.Begin();
}
/// <summary>
/// 放大Button对象
/// </summary>
/// <param name="sb"></param>
/// <param name="btn"></param>
private void MaxButton(Storyboard sb, Button btn)
{
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Width)", btn.Width, 700, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Height)", btn.Height, 480, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Top)", Canvas.GetTop(btn), 5, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Left)", Canvas.GetLeft(btn), 5, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
}
/// 放大Button对象
/// </summary>
/// <param name="sb"></param>
/// <param name="btn"></param>
private void MaxButton(Storyboard sb, Button btn)
{
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Width)", btn.Width, 700, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Height)", btn.Height, 480, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Top)", Canvas.GetTop(btn), 5, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Left)", Canvas.GetLeft(btn), 5, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
}
/// <summary>
/// 缩小Button对象
/// </summary>
/// <param name="sb"></param>
/// <param name="btn"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="Top"></param>
/// <param name="Left"></param>
private void ReduceButton(Storyboard sb, Button btn, double width, double height, double Top, double Left)
{
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Width)", btn.Width, width, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Height)", btn.Height, height, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Top)", Canvas.GetTop(btn), Top, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Left)", Canvas.GetLeft(btn), Left, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
/// 缩小Button对象
/// </summary>
/// <param name="sb"></param>
/// <param name="btn"></param>
/// <param name="width"></param>
/// <param name="height"></param>
/// <param name="Top"></param>
/// <param name="Left"></param>
private void ReduceButton(Storyboard sb, Button btn, double width, double height, double Top, double Left)
{
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Width)", btn.Width, width, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(FrameworkElement.Height)", btn.Height, height, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Top)", Canvas.GetTop(btn), Top, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
sb.Children.Add(CreateDoubleAnimation(btn,
"(Canvas.Left)", Canvas.GetLeft(btn), Left, new TimeSpan(0, 0, 0, 0, 0), TimeSpan.FromMilliseconds(1000)));
}
这是3.0的写法 4.0的朋友们可能需要修改一下。
最后实现3和4的页面状态以及动画
修改btnNum_Click事件
private void btnNum_Click(object sender, RoutedEventArgs e)
{
Button btnClick = sender as Button;
//判断执行动画
if (string.IsNullOrEmpty(clickName) == true)//初始化动画
{
clickName = btnClick.Name;
Initialization();
}
else
{
Storyboard sb = new Storyboard();
if (btnClick.Name == clickName)//还原界面
{
for (int i = 0; i < 6; i++)
{
Button temp = Buttons[i];
double left = 0;
double top = 0;
if (i < 3)//控制行Top
{
top = 2;
}
else
{
top = 248;
}
switch (i)//控制列Left
{
case 0:
case 3:
left = 2;
break;
case 1:
case 4:
left = 305;
break;
default:
left = 608;
break;
}
ReduceButton(sb, temp, 300, 240, top, left);
}
clickName = string.Empty;
}
else//位置交换
{
Button temp = this.FindName(clickName) as Button;
MaxButton(sb, btnClick);
ReduceButton(sb, temp, 200, 95, Canvas.GetTop(btnClick), 710);
clickName = btnClick.Name;
}
sb.Begin();
}
}
{
Button btnClick = sender as Button;
//判断执行动画
if (string.IsNullOrEmpty(clickName) == true)//初始化动画
{
clickName = btnClick.Name;
Initialization();
}
else
{
Storyboard sb = new Storyboard();
if (btnClick.Name == clickName)//还原界面
{
for (int i = 0; i < 6; i++)
{
Button temp = Buttons[i];
double left = 0;
double top = 0;
if (i < 3)//控制行Top
{
top = 2;
}
else
{
top = 248;
}
switch (i)//控制列Left
{
case 0:
case 3:
left = 2;
break;
case 1:
case 4:
left = 305;
break;
default:
left = 608;
break;
}
ReduceButton(sb, temp, 300, 240, top, left);
}
clickName = string.Empty;
}
else//位置交换
{
Button temp = this.FindName(clickName) as Button;
MaxButton(sb, btnClick);
ReduceButton(sb, temp, 200, 95, Canvas.GetTop(btnClick), 710);
clickName = btnClick.Name;
}
sb.Begin();
}
}
/// <summary>
/// 创建一个DoubleAnimation动画对象
/// </summary>
/// <param name="element">动画对象</param>
/// <param name="property">动画对象属性</param>
/// <param name="from">起始值</param>
/// <param name="to">结束值</param>
/// <param name="tsBeginTime">开始时间</param>
/// <param name="tsDuration">结束结束时间</param>
/// <returns></returns>
public static DoubleAnimation CreateDoubleAnimation(DependencyObject element, string property, double from,
double to, TimeSpan tsBeginTime, TimeSpan tsDuration)
{
DoubleAnimation da = new DoubleAnimation();
da.BeginTime = tsBeginTime;
da.Duration = new Duration(tsDuration);
da.To = to;
da.From = from;
da.EasingFunction = new PowerEase() { EasingMode = EasingMode.EaseOut, Power = 3 };
Storyboard.SetTarget(da, element);
Storyboard.SetTargetProperty(da, new PropertyPath(property));
return da;
}
/// 创建一个DoubleAnimation动画对象
/// </summary>
/// <param name="element">动画对象</param>
/// <param name="property">动画对象属性</param>
/// <param name="from">起始值</param>
/// <param name="to">结束值</param>
/// <param name="tsBeginTime">开始时间</param>
/// <param name="tsDuration">结束结束时间</param>
/// <returns></returns>
public static DoubleAnimation CreateDoubleAnimation(DependencyObject element, string property, double from,
double to, TimeSpan tsBeginTime, TimeSpan tsDuration)
{
DoubleAnimation da = new DoubleAnimation();
da.BeginTime = tsBeginTime;
da.Duration = new Duration(tsDuration);
da.To = to;
da.From = from;
da.EasingFunction = new PowerEase() { EasingMode = EasingMode.EaseOut, Power = 3 };
Storyboard.SetTarget(da, element);
Storyboard.SetTargetProperty(da, new PropertyPath(property));
return da;
}
第一次写博客,还请大家手下留情
![](http://bbs.silverlightchina.net/static/image/smiley/comcom/3.gif)