这个动画原来是用VS11 beta+SL5做的,回到家用vs2010跑了一下,没跑起来,重新修改了一下,在vs2010+sl5环境下成功。
截图如下:
思路很简单,波浪的部分是一个Canvas,然后用PahtGeometry填充,就可以设置波浪的背景了,对cavas或者path做个无限循环位移的动画就可以了。太阳升起落下是一个Rotation动画,然后把动画选装的中心点设置为RenderTransformOrigin="6.5,0",这个数据可以调整。
源代码可以从这里下载:http://download.csdn.net/detail/coaxhappy/4459305,如果没有分的可以从下面拷贝代码过去,写这个动画的目的就是学习如何从C#代码里控制动画,完成一些稍微复杂的动画和UI操作。
代码如下:
MainPage.xaml
<UserControl x:Class="WaterSunshine.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:ec="http://schemas.microsoft.com/expression/2010/controls" xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" xmlns:ee="http://schemas.microsoft.com/expression/2010/effects" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="600" d:DesignWidth="1200" mc:Ignorable="d"> <UserControl.Resources> <Storyboard x:Name="Storyboard3" AutoReverse="False" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="pathTest" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateX)"> <EasingDoubleKeyFrame KeyTime="0" Value="-50" /> <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0" /> </DoubleAnimationUsingKeyFrames> </Storyboard> <Storyboard x:Name="Storyboard1" RepeatBehavior="Forever"> <DoubleAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)"> <EasingDoubleKeyFrame KeyTime="0" Value="0" /> <EasingDoubleKeyFrame KeyTime="0:0:12" Value="180" /> </DoubleAnimationUsingKeyFrames> </Storyboard> </UserControl.Resources> <Grid x:Name="LayoutRoot" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="White"> <Grid VerticalAlignment="Top" d:LayoutOverrides="Width"> <Grid.Effect> <!-- <ee:BloomEffect BaseIntensity="5" BaseSaturation="0" BloomIntensity="2" /> --> <DropShadowEffect /> </Grid.Effect> <Grid.Background> <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1"> <GradientStop Offset="0" Color="#FF208EEA" /> <GradientStop Offset="1" Color="#FFD4FBF2" /> </LinearGradientBrush> </Grid.Background> </Grid> <Canvas x:Name="canvas" Height="500" VerticalAlignment="Top"> <Canvas.Background> <LinearGradientBrush StartPoint="0.5,1"> <GradientStop Offset="0.009" Color="#FF1C85EE" /> <GradientStop Offset="1" Color="#FFFDFDFD" /> </LinearGradientBrush> </Canvas.Background> <Ellipse x:Name="ellipse" Canvas.Left="50" Width="100" Height="100" Canvas.ZIndex="0" RenderTransformOrigin="6.5,0"> <Ellipse.RenderTransform> <CompositeTransform /> </Ellipse.RenderTransform> <Ellipse.Effect> <BlurEffect Radius="15" /> </Ellipse.Effect> <Ellipse.Fill> <RadialGradientBrush GradientOrigin="0.3,0.2"> <GradientStop Offset="0.009" Color="#FFEEE4AB" /> <GradientStop Offset="1" Color="#FFEAAD0C" /> </RadialGradientBrush> </Ellipse.Fill> </Ellipse> <Path x:Name="pathTest" HorizontalAlignment="Left" VerticalAlignment="Stretch" Data="" Fill="{StaticResource bgBrush}" RenderTransformOrigin="0.5,0.5" strokeThickness="0" UseLayoutRounding="False"> <Path.RenderTransform> <CompositeTransform /> </Path.RenderTransform> </Path> </Canvas> </Grid> </UserControl>
MainPage.xaml.cs
using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; using WaterSunshine.Common; namespace WaterSunshine { public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); this.SizeChanged += new SizeChangedEventHandler(MainPage_SizeChanged); } void MainPage_SizeChanged(object sender,SizeChangedEventArgs e) { double waveBlockWidth = LayoutRoot.ActualWidth + 200; canvas.Width = waveBlockWidth; double startPositionX = -100d; double startPositionY = LayoutRoot.ActualHeight * ConstValue.WAVE_START_POINTION_PROPORTION; Canvas.SetTop(ellipse,LayoutRoot.ActualHeight * 0.9d); //canvas.Margin = new Thickness(-100,-100,0); pathTest.Width = waveBlockWidth;// LayoutRoot.ActualWidth + 100; pathTest.Height = LayoutRoot.ActualHeight; Point startPoint = new Point(startPositionX,startPositionY); PathGeometry pathGeometry = pathTest.Data as PathGeometry; pathGeometry.figures.Clear(); pathGeometry.figures.Insert(0,CreatePathfigure(startPoint,ConstValue.WAVE_HEIGHT_HEIGHT,ConstValue.WAVE_LENGTH,LayoutRoot.ActualWidth + 200d,ConstValue.WAVE_PATH_stroke_Brush,ConstValue.WAVE_PATH_stroke_THICKnesS)); Pathfigure pathfigureBounds = new Pathfigure(); pathfigureBounds.StartPoint = startPoint; Linesegment linesegment1 = new Linesegment(); linesegment1.Point = startPoint; Linesegment linesegment2 = new Linesegment(); linesegment2.Point = new Point(startPositionX,LayoutRoot.ActualHeight); Linesegment linesegment3 = new Linesegment(); linesegment3.Point = new Point(LayoutRoot.ActualWidth + 100,LayoutRoot.ActualHeight); Linesegment linesegment4 = new Linesegment(); linesegment4.Point = new Point(LayoutRoot.ActualWidth + 100,startPositionY); pathfigureBounds.Segments.Add(linesegment1); pathfigureBounds.Segments.Add(linesegment2); pathfigureBounds.Segments.Add(linesegment3); pathfigureBounds.Segments.Add(linesegment4); pathGeometry.figures.Add(pathfigureBounds); (this.Resources["Storyboard3"] as Storyboard).Begin(); (this.Resources["Storyboard1"] as Storyboard).Begin(); } private Pathfigure CreatePathfigure(Point startPoint,double waveHeight,double waveLength,double totalLength,Brush strokeBrush,double strokeThickness) { Pathfigure pathfigure = new Pathfigure(); pathfigure.StartPoint = startPoint; double waveCount = Math.Ceiling((totalLength) / waveLength); for (int i = 0; i < waveCount; i++) { PathSegment pathSegment = CreateWaveSegment(new Point(startPoint.X + i * waveLength,startPoint.Y),waveHeight,waveLength); pathfigure.Segments.Add(pathSegment); } return pathfigure; } private PathSegment CreateWaveSegment(Point startPoint,double waveLength) { BezierSegment bezierSegment = new BezierSegment(); bezierSegment.Point1 = new Point(startPoint.X,startPoint.Y); bezierSegment.Point2 = new Point(startPoint.X + waveLength / 2d,startPoint.Y + waveHeight); bezierSegment.Point3 = new Point(startPoint.X + waveLength,startPoint.Y); return bezierSegment; } } }
App.xaml
<Application xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="WaterSunshine.App" > <Application.Resources> <ResourceDictionary Source="Resources/Theme1.xaml" /> </Application.Resources> </Application>
Theme1.xaml(拷贝时,注意项目结构Reources/Theme1.xaml)
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <LinearGradientBrush x:Key="bgBrush" StartPoint="0.5,1"> <GradientStop Offset="0.009" Color="#FF0E8FE8" /> <GradientStop Offset="1" Color="#FFB0E1F3" /> </LinearGradientBrush> </ResourceDictionary>
ConstValue.cs(Common/ConstValue.cs)
using System; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Ink; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace WaterSunshine.Common { public class ConstValue { public const double WAVE_START_POINTION_PROPORTION = 0.8d; public const double WAVE_HEIGHT_HEIGHT = 10; public const double WAVE_LENGTH = 50; public static Brush WAVE_PATH_stroke_Brush = new SolidColorBrush(Colors.Black); public const double WAVE_PATH_stroke_THICKnesS = 0d; } }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。