Приостановка вращения анимации, установка значения угла, а затем возобновление? - PullRequest
0 голосов
/ 09 сентября 2010

У меня есть ситуация, когда у меня есть 3d-модель с постоянной анимацией вращения.Когда пользователь касается экрана, мне бы хотелось, чтобы вращение прекратилось, и пользовательский элемент управления принял анимацию вращения.

Я попытался сделать это, приостановив анимацию, установив свойство угла длявращение локально, затем возобновление вращения.Однако из-за приоритета свойства зависимостей я обнаружил, что мои значения параметров игнорируются, пока анимация приостановлена.

Единственный обходной путь, который я мог придумать, - это сенсорное управление камерой, в то время как анимация контролирует реальную модель.К сожалению, это вызывает другие сложности в будущем, и я бы предпочел, чтобы оба действия контролировали саму модель.

   //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 Ответ

1 голос
/ 10 сентября 2010

Я столкнулся с такой же потребностью (также 3D, также вращение Model3DGroup) и сделал это следующим образом:

Когда анимация должна быть остановлена, я получаю текущее двойное значение анимированного свойства (и сохраняю его локально).

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)) при расчете длительности.

Однажды у меня было это. Я понял, что это можно обобщить для всех линейных анимаций и обобщил в Поведение / AttachedProperty.

...