1. 程式人生 > >WPF學習(15)-動畫基礎

WPF學習(15)-動畫基礎

       WPF其中核心的一個模組就是對於動畫的支援,我們知道之前更多人使用的是flash來製作動畫,但是現在flash已經不被ios支援,並且眾多平臺開始排斥flash,但是動畫的基本製作是不會變得,就好像最開始的時候,而WPF框架自帶動畫支援,確實是一個巨大的進步,意味著我們可以在我們的應用程式中構建更復雜,更具有互動性的介面,雖然很多人說只要實現功能就可以,華而不實的東西沒什麼用,但是我覺得不管是從哪個地方切入,動畫是任何一個程式設計師都要會的東西。

    <Grid>
        <Button Name="bt1" Content="Button" HorizontalAlignment="Center"  VerticalAlignment="Top" Width="50" Click="Button_Click"/>
    </Grid>

 一個簡單的按鈕,然後點選按鈕,讓按鈕的寬度變化,就是一個動畫效果

 DoubleAnimation da = new DoubleAnimation();
 da.From = 50;
 da.To = this.Width;
 da.Duration =TimeSpan.FromSeconds(5);
 bt1.BeginAnimation(Button.WidthProperty,da);

   當然可以直接在xaml頁面中用故事板完成剛剛的動畫,這個例子裡面動畫直接放在了按鈕的事件觸發器裡面。

        <Button Content="Button" HorizontalAlignment="Left" Margin="154,121,0,0" VerticalAlignment="Top" Width="75">
            <Button.Triggers>
                <EventTrigger RoutedEvent="Button.Click">
                    <BeginStoryboard >
                        <Storyboard  >
                            <DoubleAnimation From="10" To="100" Duration="0:0:5" Storyboard.TargetProperty="Width" >                                
                            </DoubleAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </EventTrigger>
            </Button.Triggers>
        </Button>

      還可以把動畫放在資源裡面,然後一樣的使用樣式關聯觸發器

    <Grid>
        <Grid.Resources>
            <Style x:Key="Mystyle" TargetType="Button">
                <Style.Triggers >
                    <Trigger Property="IsPressed" Value="true">
                        <Trigger.EnterActions>
                            <BeginStoryboard >
                                <Storyboard>
                                    <DoubleAnimation From="75" To="200" Duration="0:0:5" Storyboard.TargetProperty="Width"></DoubleAnimation>
                                </Storyboard>
                            </BeginStoryboard>
                        </Trigger.EnterActions >
                    </Trigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>
        <Button  Content="Button" Style="{StaticResource Mystyle}"  HorizontalAlignment="Left" Margin="154,121,0,0" VerticalAlignment="Top" Width="75">
        </Button>
    </Grid>

    通過以上三個例子,理解了這個動畫是基於屬性的,就是在一定時間內,不斷修改動畫對應的元素的某一個屬性,既然這樣,那麼要改什麼屬性,只要去找對應的動畫類,前面加了那個屬性的資料型別的名字,如果實在沒有就自己去實現。

       還有一個有點意思的是一個故事板(storyboard)裡面可以放多個動畫 ,  這個例子就是一個圓,不僅top在變,left也在變。 

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation From="0" To="300" Duration="0:0:20" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Top)"></DoubleAnimation>
                    <DoubleAnimation From="0" To="300" Duration="0:0:20" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Left)"></DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Canvas>
        <Ellipse Name="ee" Width="100" Height="100" Fill="Red"></Ellipse>
    </Canvas>
</Window>

       AutoReverse屬性,就是當他是true的時候,動畫結束之後會自動反轉,fillbehavior屬性,是個列舉值,Stop表示動畫結束,就會恢復到原來的值,而holdend則是繼續保持在動畫結束的地方。而這些都是TimeLine類的屬性,裡面有好多,比如是不是延遲,加速或減速執行動畫,包括上面的自動翻轉,fillbehavio,repetbehavior等,多用幾次我反正是很快就記住了。

        控制播放,前面已經接觸到了beginstoryboard,還有包括Pausestoryboard,ResumeStoryboard,stopstoryboard,seekstoryboard,setstoryboardspeedratio,skipstoryboardtofill,removestoryboard,看名字就可以大概看出是幹什麼用的。

        下面的例子就闡述瞭如何控制動畫的開始,結束,暫停,恢復和跳轉,完全使用的是XAML。

<Window x:Class="WpfApplication5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Triggers>
        <EventTrigger SourceName="cmdstart" RoutedEvent="Button.Click">
            <BeginStoryboard Name="mybs">
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="im1" From="1" To="0" Duration="0:0:10" Storyboard.TargetProperty="Opacity"></DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
        <EventTrigger SourceName="cmdpause" RoutedEvent="Button.Click">
            <PauseStoryboard BeginStoryboardName="mybs"></PauseStoryboard>
        </EventTrigger>
        <EventTrigger SourceName="cmdresume" RoutedEvent="Button.Click">
            <ResumeStoryboard BeginStoryboardName="mybs"></ResumeStoryboard>
        </EventTrigger>
        <EventTrigger SourceName="cmdstop" RoutedEvent="Button.Click">
            <StopStoryboard BeginStoryboardName="mybs"></StopStoryboard>
        </EventTrigger>
        <EventTrigger SourceName="cmdmiddle" RoutedEvent="Button.Click">
            <SeekStoryboard BeginStoryboardName="mybs" Offset="0:0:5"></SeekStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Grid>
        <StackPanel>
            <Image Name="im1" Height="100" Source="c:\users\hongbo\documents\visual studio 2013\Projects\WpfApplication5\WpfApplication5\Images\Alarm.png"></Image>
            <Image Height="100" Source="c:\users\hongbo\documents\visual studio 2013\Projects\WpfApplication5\WpfApplication5\Images\AlarmGroup.png"></Image>
            <StackPanel>
                <Button Name="cmdstart">開始</Button>
                <Button Name="cmdpause">暫停</Button>
                <Button Name="cmdresume">恢復</Button>
                <Button Name="cmdstop">停止</Button>
                <Button Name="cmdmiddle">移到中間</Button>
            </StackPanel>
        </StackPanel>       
          </Grid>
</Window>

      還有一個就是動畫緩動,可以簡單理解為為動畫增加一些效果,否則動畫就是線性地改變某個屬性值,不自然彌補生動,但是這個玩意兒我怎麼感覺應該交給設計師來做呢?好吧,咱們立志成為full statck,以下例項就是一個緩動函式的應用。

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Triggers>
        <EventTrigger RoutedEvent="Window.Loaded">
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation AutoReverse="True" From="0" To="300" Duration="0:0:10" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Top)"></DoubleAnimation>
                    <DoubleAnimation FillBehavior="Stop" From="0" To="300" Duration="0:0:10" Storyboard.TargetName="ee" Storyboard.TargetProperty="(Canvas.Left)"></DoubleAnimation>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger>
    </Window.Triggers>
    <Canvas>
        <Ellipse Name="ee" Width="100" Height="100" Fill="Red"></Ellipse>
    </Canvas>
</Window>