2012-06-04 38 views
4

我尋找這個特殊的東西,因爲我認爲這是相當重要和令人費解的事情,但我沒有發現任何事情。我在想的是WPF和Silverlight動畫中的時間縮放。WPF/SL動畫時間縮放

假設我們有一個持續4秒的動畫,並且動畫的屬性從0到100.它是自動反轉的,或者有一個補充動畫可以反轉它的效果,這並不重要。假設觸發此動畫的事件是一個簡單的MouseOver。

下面是問題:我將光標懸停在某個元素上。該物業在4秒內從0到100。我將光標移動1秒,財產從100到75,然後我將鼠標懸停回來。現在該物業在4秒內從75到100。對用戶來說很明顯,動畫運行速度要慢4倍。有什麼方法可以縮放動畫的時間嗎?如果我想讓這個動畫在1秒內從75到100,我該怎麼做?我自己正在考慮一個可能需要四個參數(絕對開始和結束,實際開始和整個時間間隔的時間跨度)的轉換器,然後吐出適當的時間。有沒有更優雅的方式?

我注意到,動畫速度很快時通常不會出現問題。當動畫以0.2s或0.1s運行時,人類並沒有真正觀察到速度的差異,也許所有的動畫應該儘可能快以免使經驗惡化。但是請理論上對待這個問題(因此沒有代碼示例)。我只是好奇,如果有任何適當的方式來縮放動畫時間。

如果在網上的某個地方有我的問題的答案,請直接告訴我那裏。

Paweł

P.S.不要介意我的英語,我不是母語;)

回答

0

我做了一些更多的研究。看起來縮放動畫時間的唯一好方法是使用MultiConverter,它接受邊界值(例如,前面的示例中的0和100),動畫屬性的當前值以及完整動畫的運行時間(例如我的例子中是4s)。然後它應該計算動畫應該完成的百分比(所以如果當前值是75,並且全部範圍是0-100,那麼剩下25%的動畫),並且返回值應該是前述的原始時間範圍(4的25%是1秒)。也許這不是實現目標的最優雅的方式,但它似乎應該起作用。

0

我知道你的確切問題並不是一個答案,但一種方法是獲取MouseEnterMouseLeave,檢查當前的動畫狀態並暫停或恢復它:

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="AnimationTest.MainPage" 
    Width="640" Height="480"> 
    <UserControl.Resources> 
     <Storyboard x:Name="Rotate" AutoReverse="True"> 
      <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.Rotation)" Storyboard.TargetName="textBlock"> 
       <EasingDoubleKeyFrame KeyTime="0" Value="0"/> 
       <EasingDoubleKeyFrame KeyTime="0:0:4" Value="100"/> 
      </DoubleAnimationUsingKeyFrames> 
     </Storyboard> 
    </UserControl.Resources> 

    <Grid x:Name="LayoutRoot" Background="White"> 
     <TextBlock x:Name="textBlock" Margin="197,216,200,215" TextWrapping="Wrap" Text="My Funky Text" FontSize="32" RenderTransformOrigin="0.5,0.5" MouseEnter="textBlock_MouseEnter" MouseLeave="textBlock_MouseLeave"> 
      <TextBlock.RenderTransform> 
       <CompositeTransform/> 
      </TextBlock.RenderTransform> 
     </TextBlock> 
    </Grid> 
</UserControl> 

代碼:

private void textBlock_MouseEnter(object sender, MouseEventArgs e) 
{ 
    var state = Rotate.GetCurrentState(); 
    if (state == ClockState.Stopped || state == ClockState.Filling) { Rotate.Begin(); } else Rotate.Resume(); 
} 

private void textBlock_MouseLeave(object sender, MouseEventArgs e) 
{ 
    Rotate.Pause(); 
} 
+0

謝謝,但正如你所說 - 你不能回答我的具體問題:) –

0

我的動畫按照您描述的方式線性行爲,我也遇到了同樣的問題。我無法在XAML中使用WPF觸發器找到解決方案,而無需編寫代碼隱藏。

然後我開始使用VisualStateManager而不是觸發器(它支持WPF 4和Silverlight)。所有動畫的表現完全像你期望的那樣!

我會推薦使用VisualStateManager的Expression Blend 4,因爲只需幾秒鐘即可使用UI配置對象的各種狀態。