暂停动画旋转,设置角度值,然后再恢复?

时间:2010-09-09 06:49:01

标签: c# .net wpf dependency-properties

我的情况是我有一个具有恒定旋转动画的3D模型。当用户触摸屏幕时,我希望旋转停止,并且用户控制接管旋转动画。

我尝试通过暂停动画,在本地设置旋转的角度属性,然后恢复旋转来做到这一点。但是,我发现由于dependency property precedence,我的设置值会在动画暂停时被忽略。

我能想到的唯一解决方法是让触摸控制相机,而动画控制实际模型。不幸的是,这会导致其他复杂问题,我更倾向于两种行为都控制着模型本身。

   //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 个答案:

答案 0 :(得分:1)

我遇到了同样的需求(也是3D,也是Model3DGroup旋转)并且这样做了:

当动画需要停止时,我获得动画属性的当前double值(并将其存储在本地)。

var temp = myAxisAngleRotation.Angle;

然后我使用

从依赖属性中删除动画
myAxisAngleRotation.BeginAnimation(AxisAngleRotation3D.AngleProperty, null);

并将动画依赖项属性设置为存储值。

myAxisAngleRotation.Angle = temp;

当动画需要恢复时,我创建一个以当前值开头的新动画。

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

完成!

如果您希望动画保持恒定速度,则在计算持续时间时必须考虑距离(Math.Abs(anim.To-anim.From))。

我有了这个。我意识到这可以推广到所有线性动画,并将其推广到Behavior / AttachedProperty。