Silverlight & Blend动画设计系列十三:三角函数(Trigonometry)动画之飘落的雪花(Falling Snow)...
平时我们所看到的雪花(Falling Snow)飘飘的效果实际上也是一个动画,是由许多的动画对象共同完成的一个界面效果。对于不同大小的雪片可以通过缩放变换(ScaleTransform)功能特性确定,雪片飘落是存在于一个空间之中,通过不同的透明度值可使雪花看上去具有一定的空间视觉,雪花的飘落过程是由三角函数的原理实现的左右滑落效果,并可根据随机生成数字作为雪花飘落的速度。
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><Canvasx:Name="LayoutRoot">
<PathData="F1M24.667480,10.681641L24.017578,9.555176L21.143066,9.555176L22.395996,7.384766L
21.746094,6.258301L20.445313,6.258301L18.541992,9.555176L14.284668,9.555176L
16.413574,5.868652L20.220215,5.868652L20.870605,4.742188L20.220215,3.615723L
17.713379,3.615723L19.151367,1.126465L18.500977,0.000000L17.200195,0.000000L
15.763184,2.489746L14.509766,0.318848L13.209473,0.318848L12.559082,1.444824L
14.462402,4.742188L12.333984,8.428711L10.205078,4.742188L12.108887,1.444824L
11.458496,0.318848L10.157715,0.318848L8.904785,2.489746L7.467285,0.000000L
6.166992,0.000000L5.516602,1.126465L6.954102,3.615723L4.447266,3.615723L
3.796875,4.742188L4.447266,5.868652L8.254395,5.868652L10.383301,9.555176L
6.125977,9.555176L4.222656,6.258301L2.921875,6.258301L2.271484,7.384766L
3.524902,9.555176L0.650391,9.555176L0.000000,10.681641L0.650391,11.807617L
3.524902,11.807617L2.271484,13.978516L2.921875,15.104980L4.222656,15.104980L
6.125977,11.807617L10.383301,11.807617L8.254395,15.494629L4.447266,15.494629L
3.796875,16.621094L4.447266,17.747070L6.954102,17.747070L5.516602,20.236816L
6.166992,21.363281L7.467285,21.363281L8.904785,18.873535L10.157715,21.044434L
11.458496,21.044434L12.108887,19.917969L10.205078,16.621094L12.333984,12.934082L
14.462402,16.621094L12.559082,19.917969L13.209473,21.044434L14.509766,21.044434L
15.762695,18.873535L17.200195,21.363281L18.500977,21.363281L19.151367,20.236816L
17.713379,17.747070L20.220215,17.747070L20.870605,16.621094L20.220215,15.494629L
16.413574,15.494629L14.284668,11.807617L18.541992,11.807617L20.445313,15.104980L
21.746094,15.104980L22.395996,13.978516L21.143066,11.807617L24.017578,11.807617L
24.667480,10.681641Z"Fill="#FFFFFFFF"Width="24"Height="24"RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransformx:Name="ScaleFlake"ScaleX="1"ScaleY="1"/>
<RotateTransformx:Name="RotateFlake"Angle="0"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
<PathData="F1M24.667480,10.681641L24.017578,9.555176L21.143066,9.555176L22.395996,7.384766L
21.746094,6.258301L20.445313,6.258301L18.541992,9.555176L14.284668,9.555176L
16.413574,5.868652L20.220215,5.868652L20.870605,4.742188L20.220215,3.615723L
17.713379,3.615723L19.151367,1.126465L18.500977,0.000000L17.200195,0.000000L
15.763184,2.489746L14.509766,0.318848L13.209473,0.318848L12.559082,1.444824L
14.462402,4.742188L12.333984,8.428711L10.205078,4.742188L12.108887,1.444824L
11.458496,0.318848L10.157715,0.318848L8.904785,2.489746L7.467285,0.000000L
6.166992,0.000000L5.516602,1.126465L6.954102,3.615723L4.447266,3.615723L
3.796875,4.742188L4.447266,5.868652L8.254395,5.868652L10.383301,9.555176L
6.125977,9.555176L4.222656,6.258301L2.921875,6.258301L2.271484,7.384766L
3.524902,9.555176L0.650391,9.555176L0.000000,10.681641L0.650391,11.807617L
3.524902,11.807617L2.271484,13.978516L2.921875,15.104980L4.222656,15.104980L
6.125977,11.807617L10.383301,11.807617L8.254395,15.494629L4.447266,15.494629L
3.796875,16.621094L4.447266,17.747070L6.954102,17.747070L5.516602,20.236816L
6.166992,21.363281L7.467285,21.363281L8.904785,18.873535L10.157715,21.044434L
11.458496,21.044434L12.108887,19.917969L10.205078,16.621094L12.333984,12.934082L
14.462402,16.621094L12.559082,19.917969L13.209473,21.044434L14.509766,21.044434L
15.762695,18.873535L17.200195,21.363281L18.500977,21.363281L19.151367,20.236816L
17.713379,17.747070L20.220215,17.747070L20.870605,16.621094L20.220215,15.494629L
16.413574,15.494629L14.284668,11.807617L18.541992,11.807617L20.445313,15.104980L
21.746094,15.104980L22.395996,13.978516L21.143066,11.807617L24.017578,11.807617L
24.667480,10.681641Z"Fill="#FFFFFFFF"Width="24"Height="24"RenderTransformOrigin="0.5,0.5">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransformx:Name="ScaleFlake"ScaleX="1"ScaleY="1"/>
<RotateTransformx:Name="RotateFlake"Angle="0"/>
</TransformGroup>
</Path.RenderTransform>
</Path>
</Canvas>
通过路径(Path)可绘制雪花界面,为此只需要提供一个根据不同参数构造不同的雪花界面效果的接口,既构造方法:
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->//根据不同的参数构造雪花对象
publicSnowflake(doubleLeft,doubleTop,doubleOpacity)
{
InitializeComponent();
//随机速度
Speed=Rand.Next(5);
if(Speed<1)
{
Speed=1;
}
//随机位置、弧度、角度
DriftPosition=Left;
DriftRange=Rand.Next(50);
DriftAngle=Rand.Next(270);
Spin=Rand.Next(5);
ScaleFlake.ScaleX=ScaleFlake.ScaleY=Rand.Next(25,100)/100.0;
Canvas.SetLeft(this,Left);
Canvas.SetTop(this,Top);
this.Opacity=Opacity;
Position.X=Left;
Position.Y=Top;
}
publicSnowflake(doubleLeft,doubleTop,doubleOpacity)
{
InitializeComponent();
//随机速度
Speed=Rand.Next(5);
if(Speed<1)
{
Speed=1;
}
//随机位置、弧度、角度
DriftPosition=Left;
DriftRange=Rand.Next(50);
DriftAngle=Rand.Next(270);
Spin=Rand.Next(5);
ScaleFlake.ScaleX=ScaleFlake.ScaleY=Rand.Next(25,100)/100.0;
Canvas.SetLeft(this,Left);
Canvas.SetTop(this,Top);
this.Opacity=Opacity;
Position.X=Left;
Position.Y=Top;
}
出了根据不同参数生成雪花对象外,还需提供一个动态改变雪花位置的接口,也就是动态改变雪花的X,Y的坐标值。
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->//根据三角函数计算雪片下落过程(Y坐标)中的左右(X方向)浮动效果
publicvoidMoveFlake()
{
Position.Y+=Speed;
Position.X=DriftPosition+Math.Cos(DriftAngle)*DriftRange;
RotateFlake.Angle+=Spin;
if(Position.Y>AppHeight)
{
Position.Y=-this.Height;
}
Canvas.SetLeft(this,Position.X);
Canvas.SetTop(this,Position.Y);
DriftAngle+=DriftSpeed;
}
publicvoidMoveFlake()
{
Position.Y+=Speed;
Position.X=DriftPosition+Math.Cos(DriftAngle)*DriftRange;
RotateFlake.Angle+=Spin;
if(Position.Y>AppHeight)
{
Position.Y=-this.Height;
}
Canvas.SetLeft(this,Position.X);
Canvas.SetTop(this,Position.Y);
DriftAngle+=DriftSpeed;
}
在主程序中需要定义一个动画,用于控制雪花下落和角度旋转:
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />--><UserControl.Resources>
<Storyboardx:Name="Snowfall"Duration="00:00:00"/>
</UserControl.Resources>
<Storyboardx:Name="Snowfall"Duration="00:00:00"/>
</UserControl.Resources>
通过主程序动态的随机构造雪花对象并添加到界面中,然后统一启动动画就实现了飘落的雪花效果,其完整的主控程序如下代码块:
<!--<br/ /><br/ />Code highlighting produced by Actipro CodeHighlighter (freeware)<br/ />http://www.CodeHighlighter.com/<br/ /><br/ />-->publicpartialclassMainPage:UserControl
{
privateList<Snowflake>Flake;
privateList<Point>XYStart;
privateList<double>OpacityValue;
privateintMaxFlakes=250;
privateRandomRand=newRandom();
publicMainPage()
{
InitializeComponent();
//雪花集合--初始化250个雪花对象并同事进行动画处理
Flake=newList<Snowflake>(MaxFlakes);
//雪花坐标集合
XYStart=newList<Point>(MaxFlakes);
//不透明度集合
OpacityValue=newList<double>(MaxFlakes);
for(inti=0;i<MaxFlakes;i++)
{
//不同的起止坐标
PointnewPoint=newPoint(Rand.Next((int)LayoutRoot.Width),Rand.Next((int)LayoutRoot.Height));
XYStart.Add(newPoint);
//不同透明度值
OpacityValue.Add(Rand.NextDouble());
}
InitFlakes();
Snowfall.Completed+=newEventHandler(Snowfall_Completed);
Snowfall.Begin();
}
privatevoidInitFlakes()
{
//循环生成雪花冰添加到界面
for(inti=0;i<MaxFlakes;i++)
{
Snowflakeflake=newSnowflake(XYStart[i].X,XYStart[i].Y,OpacityValue[i]);
Flake.Add(flake);
flake.AppHeight=LayoutRoot.Height;
LayoutRoot.Children.Add(flake);
}
}
//动画完成后继续开始动画的执行
privatevoidSnowfall_Completed(objectsender,EventArgse)
{
foreach(SnowflakeflakeinFlake)
{
flake.MoveFlake();
}
Snowfall.Begin();
}
}
{
privateList<Snowflake>Flake;
privateList<Point>XYStart;
privateList<double>OpacityValue;
privateintMaxFlakes=250;
privateRandomRand=newRandom();
publicMainPage()
{
InitializeComponent();
//雪花集合--初始化250个雪花对象并同事进行动画处理
Flake=newList<Snowflake>(MaxFlakes);
//雪花坐标集合
XYStart=newList<Point>(MaxFlakes);
//不透明度集合
OpacityValue=newList<double>(MaxFlakes);
for(inti=0;i<MaxFlakes;i++)
{
//不同的起止坐标
PointnewPoint=newPoint(Rand.Next((int)LayoutRoot.Width),Rand.Next((int)LayoutRoot.Height));
XYStart.Add(newPoint);
//不同透明度值
OpacityValue.Add(Rand.NextDouble());
}
InitFlakes();
Snowfall.Completed+=newEventHandler(Snowfall_Completed);
Snowfall.Begin();
}
privatevoidInitFlakes()
{
//循环生成雪花冰添加到界面
for(inti=0;i<MaxFlakes;i++)
{
Snowflakeflake=newSnowflake(XYStart[i].X,XYStart[i].Y,OpacityValue[i]);
Flake.Add(flake);
flake.AppHeight=LayoutRoot.Height;
LayoutRoot.Children.Add(flake);
}
}
//动画完成后继续开始动画的执行
privatevoidSnowfall_Completed(objectsender,EventArgse)
{
foreach(SnowflakeflakeinFlake)
{
flake.MoveFlake();
}
Snowfall.Begin();
}
}
推荐资源:
《Function Silverlight 3 Animation》----本篇中使用的示例素材选自此书