Pausing an animation rotation, setting the angle value, then resuming later?

守給你的承諾、 提交于 2019-12-24 21:53:56

问题


I have a situation where I have a 3d Model that has a constant rotation animation. When a user touches the screen, I would like the rotation to stop, and the user's control to take over the animation of the rotation.

I tried to do this by pausing the animation, setting the angle property of the rotation locally, then resuming the rotation. However, I discovered due to dependency property precedence, my setting values is ignored while the animation is paused.

The only workaround I could come up with was to have the touch control the camera, while the animation controls the actual model. Unfortunately this causes other complexities down the line and I'd much rather that both actions control the model itself.

   //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();
    }

回答1:


I have come across the same need (also 3D, also Model3DGroup rotation) and did it this way:

When the animation needs to stop I get the current double value of the animated property (and store it locally).

var temp = myAxisAngleRotation.Angle;

I then remove the animation from the dependency property using

myAxisAngleRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, null);

and set the animated dependency property to the stored value.

myAxisAngleRotation.Angle = temp;

When the animation needs to resume I create a new animation that starts with the current value.

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);

Done!

If you want your animation at a constant speed you will have to take the distance (Math.Abs(anim.To-anim.From)) into account when calculating the duration.

Once I had this. I realized this can be generalized for all linear animations and generalized it into a Behavior/AttachedProperty.



来源:https://stackoverflow.com/questions/3674369/pausing-an-animation-rotation-setting-the-angle-value-then-resuming-later

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!