title: How to make the duration of an animation dynamic?
body: <p>Let's imagine we have an animation that changes a Rectangle's width from <strong>50 to 150</strong> when user moves the cursor over it and back from <strong>150 to 50</strong> when user moves the cursor away. Let the duration of each animation be <strong>1 second</strong>.</p>
  
  <p>Everything is OK if user moves the cursor over the rectangle, then waits for 1 second for animation to finish, and then moves the cursor away from the rectangle. Two animations take 2 seconds totally and their speed is exactly what we are expecting to be.</p>
  
  <p>But if user moves the cursor away before the first animation (50 -> 150) is finished, the second animation's duration will be 1 second but the speed of it will be very slow. I mean, the second animation will animate the rectangle's width not from <strong>150 to 50</strong> but from let's say <strong>120 to 50</strong> or from <strong>70 to 50</strong> if you take cursor away very fast. But for the same <strong>1 second</strong>!</p>
  
  <p>So what I want to understand is how to make the duration of the "backwards" animation to be <strong>dynamic</strong>. Dynamic based on at what point the first animation was stopped. Or, if I specify <code>From</code> and <code>To</code> values to 150 and 50, <code>Duration</code> to 1 seconds and rectangle width will be 100 – WPF would calculate by itself that animation is 50% done.</p>
  
  <p>I was testing different ways to use animation like Triggers, EventTrigger in style, and VisualStateGroups but no success.</p>
  
  <p>Here is a XAML sample that shows my problem. If you want to see by yourself what I am talking about, move the cursor over the rectangle, wait for 1-2 seconds (first animation is finished) then move the cursor away. After that, move the cursor over the rectangle for like 0.25 seconds and move it away. You will see that the rectangle's width changes very slowly.</p>
  
  <pre><code>&lt;Rectangle Width="50"
             Height="100"
             HorizontalAlignment="Left"
             Fill="Black"&gt;
  &lt;Rectangle.Triggers&gt;
      &lt;EventTrigger RoutedEvent="MouseEnter"&gt;
          &lt;BeginStoryboard&gt;
              &lt;Storyboard&gt;
                  &lt;DoubleAnimation Storyboard.TargetProperty="Width"
                                   To="150"
                                   Duration="0:0:1" /&gt;
              &lt;/Storyboard&gt;
          &lt;/BeginStoryboard&gt;
      &lt;/EventTrigger&gt;
      &lt;EventTrigger RoutedEvent="MouseLeave"&gt;
          &lt;BeginStoryboard&gt;
              &lt;Storyboard&gt;
                  &lt;DoubleAnimation Storyboard.TargetProperty="Width" /&gt;
              &lt;/Storyboard&gt;
          &lt;/BeginStoryboard&gt;
      &lt;/EventTrigger&gt;
  &lt;/Rectangle.Triggers&gt;
  </code></pre>
  
  <p></p>
  
  <p>Also, I would like to explain what calculation I am expecting to see.
  So let's imagine another animation that goes from <strong>100 to 1100</strong> and has a duration of <strong>2 seconds</strong>. If we stop it at the point of <strong>300</strong>, it must start to go back to <strong>100</strong> but not for 2 seconds but for:</p>
  
  <pre><code>((300 - 100) / (1100 - 100)) * 2s = 0.4s
  </code></pre>
  
  <p>If we stop at 900, duration will be:</p>
  
  <pre><code>((900 - 100) / (1100 - 100)) * 2s = 1.6s
  </code></pre>
  
  <p>And if we let animation finish normally it will be:</p>
  
  <pre><code>((1100 - 100) / (1100 - 100)) * 2s = 2s
  </code></pre>