private void Scenario3EasingFunctionChanged(object sender, SelectionChangedEventArgs e) { // stop the storyboard Scenario3Storyboard.Stop(); EasingFunctionBase easingFunction = null; // select an easing function based on the user's selection ComboBoxItem selectedFunctionItem = Scenario3FunctionSelector.SelectedItem as ComboBoxItem; if (selectedFunctionItem != null) { switch (selectedFunctionItem.Content.ToString()) { case "BounceEase": easingFunction = new BounceEase(); break; case "CircleEase": easingFunction = new CircleEase(); break; case "ExponentialEase": easingFunction = new ExponentialEase(); break; case "PowerEase": easingFunction = new PowerEase() { Power = 0.5 }; break; default: break; } } // if no valid easing function was specified, let the storyboard stay stopped and do not continue if (easingFunction == null) return; ComboBoxItem selectedEasingModeItem = Scenario3EasingModeSelector.SelectedItem as ComboBoxItem; // select an easing mode based on the user's selection, defaulting to EaseIn if no selection was given if (selectedEasingModeItem != null) { switch (selectedEasingModeItem.Content.ToString()) { case "EaseOut": easingFunction.EasingMode = EasingMode.EaseOut; break; case "EaseInOut": easingFunction.EasingMode = EasingMode.EaseInOut; break; default: easingFunction.EasingMode = EasingMode.EaseIn; break; } } // plot a graph of the easing function PlotEasingFunctionGraph(easingFunction, 0.005); RectanglePositionAnimation.EasingFunction = easingFunction; GraphPositionMarkerYAnimation.EasingFunction = easingFunction; // start the storyboard Scenario3Storyboard.Begin(); }
/// <summary> /// Helper method to create animation storyboards to animate jobs firing from /// UserGroups to the Mac. /// </summary> /// <param name="from">Point to fire from</param> /// <param name="to">Point to fire at</param> /// <param name="color">Color of object to fire</param> /// <returns>Storyboard of requested animation</returns> private Storyboard AnimateJobCreation(Point from, Point to, Color color) { // Initialize a new instance of the CompositeTransform which allows you // apply multiple different transforms to the animated object this.JobIcon.Fill = new SolidColorBrush(color); this.JobIcon.RenderTransform = new CompositeTransform(); // Create the timelines DoubleAnimationUsingKeyFrames animationX = new DoubleAnimationUsingKeyFrames(); DoubleAnimationUsingKeyFrames animationY = new DoubleAnimationUsingKeyFrames(); DoubleAnimationUsingKeyFrames opacity = new DoubleAnimationUsingKeyFrames(); // Set up Easing functions ExponentialEase easingFunction = new ExponentialEase(); easingFunction.EasingMode = EasingMode.EaseInOut; // Add key frames to the timeline animationX.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.Zero, Value = from.X }); animationX.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(MILLI_PER_SEC / 2), Value = to.X, EasingFunction = easingFunction }); animationY.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.Zero, Value = from.Y }); animationY.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(MILLI_PER_SEC / 2), Value = to.Y, EasingFunction = easingFunction }); opacity.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.Zero, Value = 1 }); opacity.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds((MILLI_PER_SEC / 2) - (MILLI_PER_SEC / 5)), Value = 1 }); opacity.KeyFrames.Add(new EasingDoubleKeyFrame { KeyTime = TimeSpan.FromMilliseconds(MILLI_PER_SEC / 2), Value = 0, EasingFunction = easingFunction }); // Notice the first parameter takes a timeline object not the storyboard itself Storyboard.SetTargetProperty(animationX, "(UIElement.RenderTransform).(CompositeTransform.TranslateX)"); Storyboard.SetTargetProperty(animationY, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)"); Storyboard.SetTargetProperty(opacity, "(UIElement.Opacity)"); Storyboard.SetTarget(animationX, JobIcon); Storyboard.SetTarget(animationY, JobIcon); Storyboard.SetTarget(opacity, JobIcon); // Create the storyboards Storyboard storyboard = new Storyboard() { }; // Add the timelines to your storyboard storyboard.Children.Add(animationX); storyboard.Children.Add(animationY); storyboard.Children.Add(opacity); return storyboard; }
//Get Easing Function private EasingFunctionBase GetEasingFunction(Easing type) { EasingFunctionBase func = null; switch (type) { case Easing.EaseSineIn: case Easing.EaseSineOut: case Easing.EaseSineInOut: func = new SineEase(); break; case Easing.EaseCircleIn: case Easing.EaseCircleOut: case Easing.EaseCircleInOut: func = new CircleEase(); break; case Easing.EaseQuadraticIn: case Easing.EaseQuadraticOut: case Easing.EaseQuadraticInOut: func = new QuadraticEase(); break; case Easing.EaseCubicIn: case Easing.EaseCubicOut: case Easing.EaseCubicInOut: func = new CubicEase(); break; case Easing.EaseQuarticIn: case Easing.EaseQuarticOut: case Easing.EaseQuarticInOut: func = new QuarticEase(); break; case Easing.EaseQuinticIn: case Easing.EaseQuinticOut: case Easing.EaseQuinticInOut: func = new QuinticEase(); break; case Easing.EaseBackIn: case Easing.EaseBackOut: case Easing.EaseBackInOut: func = new BackEase(); break; case Easing.EaseBounceIn: case Easing.EaseBounceOut: case Easing.EaseBounceInOut: func = new BounceEase(); break; case Easing.EaseElasticIn: case Easing.EaseElasticOut: case Easing.EaseElasticInOut: func = new ElasticEase(); break; case Easing.EaseExpoIn: case Easing.EaseExpoOut: case Easing.EaseExpoInOut: func = new ExponentialEase(); break; case Easing.EasePowerIn: case Easing.EasePowerOut: case Easing.EasePowerInOut: func = new PowerEase(); break; default: break; } if (func != null) { switch ((int)type % 3) { case 0: func.EasingMode = EasingMode.EaseIn; break; case 1: func.EasingMode = EasingMode.EaseOut; break; default: func.EasingMode = EasingMode.EaseInOut; break; } } return func; }
public static void Animate(this DependencyObject target, double? from, double to, string propertyPath, int duration = 400, int startTime = 0, EasingFunctionBase easing = null, Action completed = null, bool enableDependentAnimation = false) { if (easing == null) { easing = new ExponentialEase(); } var db = new DoubleAnimation(); db.EnableDependentAnimation = enableDependentAnimation; db.To = to; db.From = from; db.EasingFunction = easing; db.Duration = TimeSpan.FromMilliseconds(duration); Storyboard.SetTarget(db, target); Storyboard.SetTargetProperty(db, propertyPath); var sb = new Storyboard(); sb.BeginTime = TimeSpan.FromMilliseconds(startTime); if (completed != null) { sb.Completed += (s, e) => { completed(); }; } sb.Children.Add(db); sb.Begin(); }
public static EasingFunctionBase GetEasingFunction(double stopTime, double friction) { // From above, we have the equation of position // // r = v_0 (mu^t - 1) / ln mu // // IEasingFunction.Ease() is a method that accepts // a normalized time as a parameter // (that is, a number between 0.0 and 1.0 such that // 0.0 represents the beginning of the animation duration and // 1.0 represents the end of the animation duration), // and which returns a normalized progress // (that is, a number between 0.0 and 1.0 such that // 0.0 represents no progress along the animation and // 1.0 represents full progress along the animation). // // In order to get the above equation of position // to work as an easing function, we need two things: // to normalize the LHS such that it varies between 0.0 and 1.0 // (corresponding to its initial position and its final position, respectively), // and to have it accept as a parameter on the RHS a normalized time, // rather than an actual time. // // First, to get a normalized LHS, we divide |r| by |r_max| (the stop distance as above) // to get the normalized position r_n: // // |r| / |r_max| = r_n = (mu^t - 1) / (mu^t_max- 1) // // Now we note that // // t = t_n t_max // // where t_max is the stop time as above and where t_n is the normalized time // to get // // r_n = (mu^(t_n t_max) - 1) / (mu^t_max- 1) // // Finally, we can take advantage of the fact that // // x^y = e^(y ln x) // // where e is Euler's number to put this in the form of // // r_n = (e^(t_n t_max ln mu) - 1) / (e^(t_max ln mu) - 1) // // and if we define a = t_max ln mu, then we have // // r_n = (e^(a t_n) - 1) / (e^a - 1) // // which is precisely the form of the exponential easing function. // So, we can use an exponential easing function here with its // Exponent property set to t_max ln mu, and it will get us what we want. // ExponentialEase ee = new ExponentialEase { Exponent = stopTime*Math.Log(friction), EasingMode = EasingMode.EaseIn }; return ee; }