`
duoerbasilu
  • 浏览: 1483368 次
文章分类
社区版块
存档分类
最新评论

Silverlight 动画实现--太阳升起、落下

 
阅读更多

这个动画原来是用VS11 beta+SL5做的,回到家用vs2010跑了一下,没跑起来,重新修改了一下,在vs2010+sl5环境下成功。

截图如下:

图片有点大,VS11下的太阳效果更好一点。

思路很简单,波浪的部分是一个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,0" EndPoint="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, 0, -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 waveHeight, 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,0" EndPoint="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;
    }
}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics