4

とても重要で不可解なことだと思ったので、この特定のものを探しましたが、それについては何も見つかりませんでした。私が考えているのは、WPFおよびSilverlightアニメーションの時間スケーリングです。

4秒間持続し、プロパティを0から100までアニメーション化するDoubleAnimationがあるとします。これは自動反転されるか、効果を反転する補完的なアニメーションがありますが、これは重要ではありません。このアニメーションをトリガーするイベントが単純なMouseOverであるとしましょう。

問題は次のとおりです。要素の上にカーソルを置きます。プロパティは4秒で0から100になります。カーソルを1秒間離すと、プロパティが100から75になり、ホバーして戻ります。これで、プロパティは4秒で75から100になります。アニメーションの実行速度が4倍遅いことはユーザーには明らかです。アニメーションの時間をスケーリングする方法はありますか?このアニメーションを1秒で75から100まで実行したい場合、どうすればよいですか?私自身、4つのパラメーター(絶対的な開始と終了、実際の開始、および間隔全体のタイムスパン)を取り、適切な時間を吐き出すコンバーターについて考えています。もっとエレガントな方法はありますか?

アニメーションが速い場合は、一般的に問題がないことに気づきました。アニメーションが0.2秒または0.1秒で実行される場合、人間は実際には速度の違いを観察しません。おそらく、すべてのアニメーションは、エクスペリエンスを低下させないように可能な限り高速である必要があります。ただし、この質問は理論的に扱ってください(したがって、コードサンプルはありません)。アニメーション時間をスケーリングする適切な方法があるかどうかだけ知りたいです。

ウェブ上のどこかに私の質問に対する答えがある場合は、そこに私を向けてください。

Paweł

PS私の英語を気にしないでください、私はネイティブスピーカーではありません;)

4

3 に答える 3

0

私はあなたの正確な質問に対する答えではないことを知っていますが、これにアプローチする1つの方法は、キャプチャMouseEnterしてMouseLeave、現在のアニメーションの状態を確認し、一時停止または再開することです。

<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();
}
于 2012-06-05T07:28:53.083 に答える
0

私はもう少し調査をしました。アニメーション時間をスケーリングする唯一の良い方法は、MultiConverterを使用することです。これは、境界値(たとえば、前の例の0と100)、アニメーション化されたプロパティの現在の値、および完全なアニメーションの実行時間を取り込みます。 (たとえば、私の例では4秒)。次に、アニメーションの何パーセントを実行するかを計算する必要があり(したがって、現在の値が75で、全範囲が0〜100の場合、アニメーションの25%が残ります)、戻り値は前述の割合になります。元のタイムスパン(4秒の25%は1秒です)。たぶんそれは目標を達成するための最もエレガントな方法ではありませんが、それはうまくいくはずです。

于 2012-06-05T14:15:06.160 に答える
0

あなたが説明するようにアニメーションを直線的に動作させることに関して、私はこれと同じ問題を抱えていました。コードビハインドを記述せずに、XAMLでWPFトリガーを使用する解決策を見つけることができませんでした。

次に、トリガー(WPF 4およびSilverlightでサポートされている)の代わりにVisualStateManagerを使用し始めました。すべてのアニメーションは、期待どおりに完全に動作しました。

UIを使用してオブジェクトのさまざまな状態を構成するのに数秒しかかからないため、VisualStateManagerの使用にはExpressionBlend4をお勧めします。

于 2012-07-27T09:18:35.253 に答える