我的情况是我有一个具有恒定旋转动画的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();
}
答案 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。