Динамическое изменение анимации вращения в WPF - PullRequest
9 голосов
/ 28 марта 2009

Я использую DoubleAnimation для анимирования свойства Angle объекта RotationTransform. Несколько раз в секунду мне нужно изменять скорость вращения в ответ на внешние данные, чтобы вращение со временем увеличивалось и / или замедлялось (плавно). В настоящее время я делаю это с помощью DoubleAnimation, которая повторяется вечно от 0,0 до 360,0 с продолжительностью X, а затем несколько раз в секунду:

  • Получить новое значение из внешних данных
  • Изменить ставку на DoubleAnimation на это значение
  • Повторно применить DoubleAnimation к свойству Angle снова

Примечание: я обнаружил, что мне пришлось изменить свойства анимации «Кому» и «От» на «текущий угол» и «текущий угол + 360» - к счастью для меня, у RotationTransform нет проблем с углами> 360 градусов - чтобы предотвратить запуск вращение снова с нулевого угла.

Мой вопрос: это разумно? Это не кажется так. Постоянное применение новых DoubleAnimations к свойству Angle при преобразовании вращения кажется неправильным - вроде как я позволяю WPF анимировать вращение, в то время как I сам анимирует скорость вращения.

Есть ли лучший способ?

1 Ответ

8 голосов
/ 28 марта 2009

На раскадровке есть настройка SpeedRatio, которая является множителем длительности. Однако вы не можете связать это, так как это не свойство зависимости.

Чтобы обойти это, вы можете использовать функцию SetSpeedRatio на раскадровке. Обратите внимание, что это работает только в том случае, если раскадровка запускается в коде (в противном случае вы получаете сообщение об ошибке).

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

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel>
      <Rectangle Margin="50" Width="50" Height="50" Fill="Red" x:Name="rc">
        <Rectangle.RenderTransform>
          <RotateTransform x:Name="TransRotate"
                           CenterX="25" CenterY="25" Angle="0" />
        </Rectangle.RenderTransform>
        <Rectangle.Resources>
          <Storyboard x:Key="spin">
            <DoubleAnimation x:Name="da" 
                             Storyboard.TargetName="TransRotate" 
                             Storyboard.TargetProperty="Angle"
                             By="360" 
                             Duration="0:0:10"  
                             AutoReverse="False" 
                             RepeatBehavior="Forever" />
          </Storyboard>
        </Rectangle.Resources>
      </Rectangle>
      <TextBox Text="{Binding Speed}" />
      <Button>Update Speed</Button>
    </StackPanel>
</Window>

Тогда код C #

{
    public Window1()
    {
        InitializeComponent();

        //create new  object
        BackgroundObject bo = new BackgroundObject();

        //binding only needed for the text box to change speed value
        this.DataContext = bo;

        //Hook up event
        bo.SpeedChanged += bo_SpeedChanged;

        //Needed to prevent an error
        Storyboard sb = (Storyboard)rc.FindResource("spin");
        sb.Begin(); 
    }

    //Change Speed
    public void bo_SpeedChanged(  object sender, int newSpeed)
    {
        Storyboard sb = (Storyboard)rc.FindResource("spin");
        sb.SetSpeedRatio(newSpeed);
    }
}

public delegate void SpeedChangedEventHandler(object sender, int newSpeed);

public class BackgroundObject
{
    public BackgroundObject()
    {
        _speed = 10;
    }

    public event SpeedChangedEventHandler SpeedChanged;

    private int _speed;
    public int Speed
    { 
        get { return _speed; }
        set { _speed = value; SpeedChanged(this,value); }
    }
}

Я уверен, что вы можете адаптироваться к вашему использованию.

...