2012-05-17 12 views
5

Abbiamo un'animazione a colori che si fonde dal rosso al bianco. Attualmente, questa è una dissolvenza lineare. Sappiamo che possiamo giocare con BeginTime della classe Storyboard e simili, ma che semplicemente ritarda l'inizio dell'intera animazione. Abbiamo anche esaminato il lato easy-in/easy-out delle cose, ma non sembrano funzionare neanche loro.Come posso tenere un'animazione per lo storyboard WPF per un secondo, prima di continuare?

In particolare, vorremmo mantenere un valore di rosso per un secondo, quindi sfumare da rosso a bianco nel successivo. Può essere fatto in puro XAML? In caso contrario, può essere eseguito in code-behind impostando manualmente uno storyboard? ... o dobbiamo usare due storyboard separati e suonarli in sequenza?

risposta

14

Diversi modi per farlo.

con fotogrammi chiave:

<Storyboard> 
    <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="Background.Color"> 
     <DiscreteColorKeyFrame Value="Red" KeyTime="0:0:0" /> 
     <DiscreteColorKeyFrame Value="Red" KeyTime="0:0:1" /> 
     <LinearColorKeyFrame Value="White" KeyTime="0:0:2" /> 
    </ColorAnimationUsingKeyFrames> 
</Storyboard> 

con due animazioni in sequenza:

<Storyboard> 
    <ColorAnimation Storyboard.TargetProperty="Background.Color" 
        From="Red" To="Red" Duration="0:0:1" /> 
    <ColorAnimation Storyboard.TargetProperty="Background.Color" 
        To="White" BeginTime="0:0:1" Duration="0:0:1" /> 
</Storyboard> 

con una funzione di andamento personalizzata:

<Storyboard> 
    <ColorAnimation Storyboard.TargetProperty="Background.Color" 
        From="Red" To="White" Duration="0:0:2"> 
     <ColorAnimation.EasingFunction> 
      <local:CustomEasingFunction /> 
     </ColorAnimation.EasingFunction> 
    </ColorAnimation> 
</Storyboard> 

In questo caso una funzione che mostra la transizione nella prima metà della durata e mantiene il valore nella seconda metà. Poiché l'EasingMode di default è EaseOut, questa funzione verrà quindi "riprodotta" all'indietro.

public class CustomEasingFunction : EasingFunctionBase 
{ 
    public CustomEasingFunction() : base() 
    { } 

    protected override double EaseInCore(double normalizedTime) 
    { 
     return (normalizedTime < 0.5) 
      ? normalizedTime * 2 
      : 1; 
    } 

    protected override Freezable CreateInstanceCore() 
    { 
     return new CustomEasingFunction(); 
    } 
} 
+0

Molto accurato ed esattamente ciò di cui avevo bisogno. Questo è un grande S.O. rispondi anche perché so che gli altri saranno felici del livello di dettaglio che hai fornito. Grazie mille! – MarqueIV

+0

Una domanda però ... sei sicuro del tuo commento nell'esempio della funzione di facilitazione? Secondo MSDN, il tempo normalizzato va da 0 a 1, non da 1 a 0 come hai detto, quindi il valore di ritorno dovrebbe essere 0 per valori inferiori a 0.5 (la prima metà della durata), quindi essere '(normalizedTime * 2) - 1 '(che è uguale a' (normalizedTime - 0.5) * 2 ') per la seconda metà, corretto? L'ho preso da qui ... http://msdn.microsoft.com/en-us/library/system.windows.media.animation.easingfunctionbase.easeincore.aspx – MarqueIV

+2

Aaah! Ho capito perché sei passato da 1 a 0. Hai impostato il parametro EasingMode sul valore predefinito che è EaseOut, che afferma che i valori restituiti da 'Ease' dovrebbero essere interpolazione al 100% meno il risultato della funzione EaseInCore, quindi tu pensando che sia passato da 1 a 0. Un doppio negativo se vuoi. Tuttavia, poiché la funzione è chiamata EaseInCore, per coerenza dovrebbe essere scritta con il tempo che va da 0 a 1, quindi EasingMode dovrebbe essere esplicitamente impostato su EaseIn, ma, di nuovo, sarebbe più chiaro in quanto la funzione rappresenterebbe il tempo trascorso correttamente. – MarqueIV

1

A seconda di come sono state scritte le animazioni, è possibile aggiungere una transizione "da" Rosso "a" Rosso che richiede un secondo all'inizio. Quindi tecnicamente l'animazione è in esecuzione, ma non sta facendo nulla. Questo può essere fatto in puro XAML.

Problemi correlati