2010-09-09 8 views
0

J'ai une situation où j'ai un modèle 3D qui a une animation de rotation constante. Quand un utilisateur touche l'écran, je voudrais que la rotation s'arrête et que l'utilisateur contrôle l'animation de la rotation.Pause d'une rotation d'animation, réglage de la valeur d'angle, puis reprise plus tard?

J'ai essayé de le faire en mettant l'animation en pause, en définissant la propriété d'angle de la rotation localement, puis en reprenant la rotation. Cependant, j'ai découvert en raison de dependency property precedence, mes valeurs de paramètre sont ignorées pendant que l'animation est en pause.

La seule solution de contournement que je pouvais proposer était d'avoir le contrôle tactile de la caméra, tandis que l'animation contrôle le modèle réel. Malheureusement, cela entraîne d'autres complexités et je préférerais que les deux actions contrôlent le modèle lui-même.

//In carousel.cs 
    public void RotateModel(double start, double end, int duration) 
    { 
     RotateTransform3D rt3D = _GroupRotateTransformY; 
     Rotation3D r3d = rt3D.Rotation; 
     DoubleAnimation anim = new DoubleAnimation(); 
     anim.From = start; 
     anim.To = end; 
     anim.BeginTime = null; 
     anim.AccelerationRatio = 0.1; 
     anim.DecelerationRatio = 0.6; 
     anim.Duration = new TimeSpan(0, 0, 0, 0, duration); 
     ac = anim.CreateClock(); 
     ac.Completed += new EventHandler(OnRotateEnded); 
     ac.Controller.Begin(); 
     r3d.ApplyAnimationClock(AxisAngleRotation3D.AngleProperty, ac); 

}

//In another file 
    void Carousel_ManipulationDelta(object sender, ManipulationDeltaEventArgs e) 
    { 
     var delta = e.DeltaManipulation;   

     RotateTransform3D rt = Carousel.RotateTransform; 

     ((AxisAngleRotation3D)rt.Rotation).Angle += (-e.DeltaManipulation.Translation.X/3000) * 360.0; 


     e.Handled = true; 


    } 

    void Carousel_PreviewTouchUp(object sender, TouchEventArgs e) 
    { 
     Carousel.ResumeRotationAnimation(); 
    } 

    void Carousel_PreviewTouchDown(object sender, TouchEventArgs e) 
    { 
     Carousel.PauseRotationAnimation(); 
    } 

Répondre

1

Je suis venu dans le même besoin (également rotation 3D, également Model3DGroup) et a fait de cette façon:

Lorsque l'animation a besoin d'arrêter je reçois le courant double valeur de la propriété animée (et la stocker localement).

var temp = myAxisAngleRotation.Angle; 

J'enlève alors l'animation à partir de la propriété de dépendance à l'aide

myAxisAngleRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, null); 

et définir la propriété de dépendance animée à la valeur mémorisée. Lorsque l'animation doit reprendre, je crée une nouvelle animation qui commence par la valeur actuelle.

DoubleAnimation anim = new DoubleAnimation(); 
anim.From = myAxisAngleRotation.Angle; 
anim.To = end; 
anim.Duration = new TimeSpan(0, 0, 0, 0, duration); 
myAxisAngleRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, anim); 

Terminé!

Si vous voulez que votre animation soit à vitesse constante, vous devrez prendre en compte la distance (Math.Abs(anim.To-anim.From)) lors du calcul de la durée.

Une fois que j'ai eu cela. J'ai réalisé que ceci peut être généralisé pour toutes les animations linéaires et généralisé dans un Behavior/AttachedProperty.