This is a migrated thread and some comments may be shown as answers.

transition effect in demos

11 Answers 292 Views
Navigation
This is a migrated thread and some comments may be shown as answers.
Henk
Top achievements
Rank 1
Henk asked on 01 May 2009, 01:49 PM
In the demo section of the Silverlight controls there is a neat transition control of the old window getting dimmed, the new window being loaded, then the old window being 'zoomed out' and finally the old window moving to the left outside the screen and the new window at the same time moving in from the right side of the screen and getting 'zoomed in' to fill the screen.
Is there any code of how to manage this or other information how to get such transition effect between f.e. two UserControls?

11 Answers, 1 is accepted

Sort by
0
Miroslav
Telerik team
answered on 04 May 2009, 08:32 AM
Hello Henk,

Currently we are using a custom transition for our Silverlight navigation framework. What happens is that every time we generate an animation for the transition, depending on the size of the transition elements.

The class is public, so you can try it out if you want:

Telerik.Windows.QuickStart.Animation.ExampleTransition

The constructor takes 4 parameters:
  1. Width of the page
  2. The Grid panel where the transition happens
  3. The mask for the "old" page (the dimming effect), a semi-transparent rectangle in our case
  4. The mask for the "new" page.

If you want, we can send you the xaml for the animation or the code for the transition. 

Regards,
Miroslav
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Henk
Top achievements
Rank 1
answered on 04 May 2009, 08:43 AM
Hello Miroslav ,

Thank you for your answer.
I would be very content If you would send the xaml and code.

Regards,
Henk
0
Ivan
Telerik team
answered on 06 May 2009, 07:16 AM
Hi Henk,

Attached, you can find an example with the requested transition. Actually this is the modified version of our online BooksExample. Below are points you should take a look at:
  • Application_Startup - here I just replaced the Transition with the new MyExampleTransition;
  • SilverlightClassLibrary1 project - here is the code of the new transition;
Hope this information helps.

Regards,
Ivan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Joe
Top achievements
Rank 1
answered on 13 May 2009, 05:00 PM
209432-booksexample-20090506-0734.zip
--> ERROR: Could not load file or assembly 'System.Web.Silverlight' or one of its dependencies. The system cannot find the file specified.
0
Valentin.Stoychev
Telerik team
answered on 14 May 2009, 09:11 AM
Hello Joe,

Do you have the ASP.NET Ajax latest framework installed?

Sincerely yours,
Valentin.Stoychev
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
mohamed
Top achievements
Rank 1
answered on 16 May 2009, 05:52 AM
thanks alot for the example code :) you really saved my life :D i'm new to this and there is a project that is required from me ...... thanks again
0
Manny
Top achievements
Rank 1
answered on 21 Nov 2009, 04:31 PM
I needed to put in the kewl effects of page transitioning in my application but I didn't want to put Telerik support in my base classes (I have my own framework which I see resembles the QuickStart framework approach chosen by the Telerik devs. So I extracted code from the examples and removed the need for Telerik.Windows.Controls.NavigationService and Telerik.Windows.Control.IFrame (and related friends). While the low-level navigation services are extremely kewl and just what I will need for v.next, my initial project is concentrating on getting my framework built and working reliably while also providing dashboard support.

I hope that others who want the kewl effect but want to use it directly in their own apps without requiring derivation from (or usage of) the Telerik QuickStart assemblies can benefit.

I refactored page transitioning code into a separate namespace so I could simplify class names (Telerik I've never been a big fan of putting everything in one namespace--Telerik.Windows.Controls.NavigationService should be in the Telerik.Windows.Control.Navigation namespace and called Service while the Telerik.Windows.Control.IFrame should be Telerik.Windows.Controls.Navigation.IFrame IMHO). Also I put the OnTransitionCompleted event into the ITransition interface so that callers can access the event handler without requiring deref'ing to a specific hard-coded class.

I hope this helps--I do have my kewl page transition effects and that's the long pole in the tent this morning!

I tried to document the classes and methods--I'm keen to see if my comments are in any way correct--Telerik support, could you take a look?

First, let's look at usage in my framework's base class. Excuse the hard-coding for the masks (background brush) this and much else needs to be abstracted and delegated to the implementing application.
    /// <summary> 
    /// Derived classes can override this method to perform custom transitioning  
    /// </summary> 
    /// <param name="oldPage">Page to navigate from</param> 
    /// <param name="newPage">Page to navigate to</param> 
    protected virtual void TransitionToNewPage(FrameworkElement oldPage, FrameworkElement newPage)  
    {  
      string flag = "";  
      try  
      {  
        // edge case--for first page no effects  
        if (oldPage == null)  
        {  
          flag = "immediate_navigate";  
          _root.Children.Add(newPage);  
          return;  
        } //if  
 
        // swiped from Telerik  
        var mask1 = new Rectangle()  
        {  
          Fill = new SolidColorBrush(Color.FromArgb(77, 8, 17, 48))  
        };  
        var mask2 = new Rectangle()  
        {  
          Fill = new SolidColorBrush(Color.FromArgb(77, 8, 17, 48))  
        };  
 
        // setup the transition  
        var grid = _root;  
        var currentPage = grid.Children[0] as BasePage;  
        Animation.ExampleTransition exampleTransition = new Animation.ExampleTransition(grid.ActualWidth, grid, mask1, mask2);  
        exampleTransition.TransitionAnimationCompleted += new EventHandler<Abr.CodeLibrary.Sl.Animation.TransitionEventArgs>(exampleTransition_TransitionAnimationCompleted);  
 
        // invoke the transition (definitely should be delegated)  
        if (this._lastTransition != null && this._lastTransition.IsRunning)  
        {  
          this._lastTransition.StopTransition();  
        }  
        exampleTransition.Begin(newPage);  
        this._lastTransition = exampleTransition;  
      }  
      catch (Exception ex)  
      {  
        throw new NavigationException("At " + flag + ": " + ex.Message, ex);  
      } //try  
    } //TransitionToNewPage  
 
    /// <summary> 
    /// A navigation transition has completed  
    /// </summary> 
    /// <param name="sender"></param> 
    /// <param name="e"></param> 
    protected void exampleTransition_TransitionAnimationCompleted(object sender, Abr.CodeLibrary.Sl.Animation.TransitionEventArgs e)  
    {  
      var transition = sender as Animation.ITransition;  
      transition.TransitionAnimationCompleted -exampleTransition_TransitionAnimationCompleted;  
    }  
 

Now the code to implement the kewl transition effects. The one thing totally not cool is the hardcoded speed ratio. This is based on the expected screen size and really needs to be defined by the application not the base class. Ah, well...
using System;  
using System.Windows;  
 
namespace Abr.CodeLibrary.Sl.Animation  
{  
  /// <summary> 
  /// Swiped from Telerik example; Base interface for all transitions.  
  /// </summary> 
  public interface ITransition  
  {  
    /// <summary> 
    /// Gets or sets a value indicating whether the transition is running.  
    /// </summary> 
    bool IsRunning { get; set; }  
 
    /// <summary> 
    /// Transitions the page.Transition between previous and next page.  
    /// </summary> 
    /// <param name="page">The next page.</param> 
    void Begin(FrameworkElement page);  
 
    /// <summary> 
    /// Stops the currently running transition.  
    /// </summary> 
    void StopTransition();  
 
    /// <summary> 
    /// Event to fire when animation completes (I did not know that it was possible  
    /// to templatize your custom event handler!).  
    /// </summary> 
    event EventHandler<TransitionEventArgs> TransitionAnimationCompleted;  
  } //ITransition  
} //namespace  
 
using System;  
using System.Windows;  
 
namespace Abr.CodeLibrary.Sl.Animation  
{  
  /// <summary> 
  /// The supporting class for transition event support  
  /// </summary> 
  public class TransitionEventArgs : EventArgs  
  {  
    /// <summary> 
    /// The target page for the transition  
    /// </summary> 
    public FrameworkElement TargetExamplePage  
    {  
      get;  
      set;  
    } //TargetExamplePage  
 
    /// <summary> 
    /// Create the event arguments  
    /// </summary> 
    /// <param name="targetExample">The target page for the transition</param> 
    public TransitionEventArgs(FrameworkElement targetExample)  
    {  
      this.TargetExamplePage = targetExample;  
    } //ctor  
  } //TransitionEventArgs  
} //namespace  
 
using System.Windows;  
 
namespace Abr.CodeLibrary.Sl.Animation  
{  
  /// <summary> 
  /// Swiped from Telerik, a helper class, used in code-initiated animations.  
  /// </summary> 
  /// <remarks> 
  /// Wow, I do not understand splines *at all*. I read the wiki very briefly and get Very Confused.  
  /// I *think* these things are to help make the kewl page horizontal rotation but I can't say  
  /// I understand even that much! Oh, well, always did suck at maths.  
  /// </remarks> 
  public class Spline  
  {  
    /// <summary> 
    /// Create one of these here spline-thingies. I have *got* to concentrate on some calculus!  
    /// </summary> 
    /// <param name="x1">Value 1 on x-axis</param> 
    /// <param name="y1">Value 1 on y-axis</param> 
    /// <param name="x2">Value 2 on x-axis</param> 
    /// <param name="y2">Value 2 on y-axis</param> 
    public Spline(double x1, double y1, double x2, double y2)  
    {  
      this.Point1 = new Point(x1, y1);  
      this.Point2 = new Point(x2, y2);  
    } //ctor  
 
    /// <summary> 
    /// Defines the x1-y1 point  
    /// </summary> 
    public Point Point1  
    {  
      get;  
      set;  
    } //Point1  
 
    /// <summary> 
    /// Defines the x2-y2 point  
    /// </summary> 
    public Point Point2  
    {  
      get;  
      set;  
    } //Point2  
  } //Spline  
} //namespace  
 
using System;  
using System.Windows;  
using System.Windows.Media;  
using System.Windows.Media.Animation;  
 
namespace Abr.CodeLibrary.Sl.Animation  
{  
  /// <summary> 
  /// Taken from Telerik example Silverlight application, this class is used to  
  /// define all animation extensions. Experimenting with advanced animation  
  /// in Silverlight.  
  /// </summary> 
  public static class Extensions  
  {  
    /// <summary> 
    /// Linq not available in my Silverlight .NET references, rolling this myself.  
    /// </summary> 
    /// <param name="args"></param> 
    /// <returns></returns>  
    internal static System.Collections.Generic.List<double> ToList(params double[] args)  
    {  
      System.Collections.Generic.List<double> result = new System.Collections.Generic.List<double>();  
      foreach (double arg in args) { result.Add(arg); }  
      return result;  
    } //ToList  
 
    /// <summary> 
    /// Create an animation object for a given element. Operations can  
    /// be performed on this animation.  
    /// </summary> 
    /// <param name="target">The UI element to animate</param> 
    /// <returns>The created animation context</returns> 
    public static Context Animate(this FrameworkElement target)  
    {  
      var result = new Context();  
      result.Targets.Add(target);  
      return result;  
    } //ctor  
 
    /// <summary> 
    /// Perform a scaling using time-value pairs  
    /// </summary> 
    /// <param name="target">The animation to affect</param> 
    /// <param name="args">Time and value pairs</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Scale(this Context target, params double[] args)  
    {  
      var values = ToList(args);  
 
      if (args.Length % 2 != 0)  
      {  
        throw new InvalidOperationException("Params should come in a time-value pair");  
      } //if  
 
      foreach (var element in target.Targets)  
      {  
        var scaleX = new DoubleAnimationUsingKeyFrames();  
        Storyboard.SetTarget(scaleX, element);  
        Storyboard.SetTargetProperty(scaleX, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)"));  
 
        var scaleY = new DoubleAnimationUsingKeyFrames();  
        Storyboard.SetTarget(scaleY, element);  
        Storyboard.SetTargetProperty(scaleY, new PropertyPath("(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)"));  
 
        for (int i = 0; i < values.Count; i += 2)  
        {  
          scaleX.KeyFrames.Add(new SplineDoubleKeyFrame()  
          {  
            KeyTimeKeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(values[i])),  
            Value = values[i + 1]  
          });  
 
          scaleY.KeyFrames.Add(new SplineDoubleKeyFrame()  
          {  
            KeyTimeKeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(values[i])),  
            Value = values[i + 1]  
          });  
        } //for  
 
        target.Instance.Children.Add(scaleX);  
        target.Instance.Children.Add(scaleY);  
      } //for  
 
      targettarget.StartIndex = target.EndIndex;  
      target.EndIndex += 2 * target.Targets.Count;  
 
      return target;  
    } //Scale  
 
    /// <summary> 
    /// Move the target on the x-axis  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="args">Values to affect the <code>TranslateTransform.X</code> transform element</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context MoveX(this Context target, params double[] args)  
    {  
      return target.SingleProperty("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)", args);  
    } //MoveX  
 
#if !WPF  
    /// <summary> 
    /// Move the target on the y-axis  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="args">Values to affect the <code>TranslateTransform.Y</code> transform element</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context MoveY(this Context target, params double[] args)  
    {  
      return target.SingleProperty("(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)", args);  
    }  
#endif  
 
    /// <summary> 
    /// Affect target opacity  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="args">Values to affect the <code>UIElement.Opacity</code> property</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Opacity(this Context target, params double[] args)  
    {  
      return target.SingleProperty("(UIElement.Opacity)", args);  
    }  
 
    /// <summary> 
    /// Splines are weird to me--I don't really understand the math. So I take on faith  
    /// that these are useful and exactly what we need to get the turning effect that  
    /// looks so kewl on the Telerik example application.  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="spline">A spline object to use for setting our animation splines</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Splines(this Context target, Spline spline)  
    {  
      return target.Splines(1, spline.Point1.X, spline.Point1.Y, spline.Point2.X, spline.Point2.Y);  
    } //Splines  
 
    /// <summary> 
    /// Set animation splines based on a specific index  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="index">The index to set within our animation splines</param> 
    /// <param name="spline">A spline object to use for setting our animation splines</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Splines(this Context target, int index, Spline spline)  
    {  
      return target.Splines(index, spline.Point1.X, spline.Point1.Y, spline.Point2.X, spline.Point2.Y);  
    } //Splines  
 
    /// <summary> 
    /// The main worker function for setting splines. Allows an index and the individual  
    /// spline values to be set explicitly.  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="index">The index to set within our animation splines</param> 
    /// <param name="x1">Weird spline parameter</param> 
    /// <param name="y1">Weird spline parameter</param> 
    /// <param name="x2">Weird spline parameter</param> 
    /// <param name="y2">Weird spline parameter</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Splines(this Context target, int index, double x1, double y1, double x2, double y2)  
    {  
      for (var num = target.StartIndex; num < target.EndIndex; num++)  
      {  
        ((target.Instance.Children[num] as DoubleAnimationUsingKeyFrames).KeyFrames[index] as SplineDoubleKeyFrame).KeySpline = new KeySpline()  
        {  
          ControlPoint1 = new Point(x1, y1),  
          ControlPoint2 = new Point(x2, y2)  
        };  
      } //for  
      return target;  
    } //Splines  
 
    /// <summary> 
    /// Set the transform origin within the targets of an animation context  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="x1">Starting origin on the x-axis</param> 
    /// <param name="x2">Although named 'x2' this is passed as the 'y' value on a point. Not sure  
    /// if this means that the parameter is misnamed or (more probably) that perhaps it's a  
    /// transform destination for the origin on the x-axis.</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Origin(this Context target, double x1, double x2)  
    {  
      foreach (var element in target.Targets)  
      {  
        element.RenderTransformOrigin = new Point(x1, x2);  
      } //foreach  
      return target;  
    } //Origin  
 
    /// <summary> 
    /// Perform an animation on a group of UI elements. Basically adds these elements  
    /// to the animation context targets (all of them).  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="newTargets">Array of UI elements to animate</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Animate(this Context target, params FrameworkElement[] newTargets)  
    {  
      target.Targets.Clear();  
      foreach (var newElement in newTargets)  
      {  
        target.Targets.Add(newElement);  
      } //foreach  
      return target;  
    } //Animate  
 
    /// <summary> 
    /// For our class to work, it's important that all elements have a common set of  
    /// transforms defined. This allows us to perform many types of transforms as desired  
    /// while ensuring that the appropriate transform support object does indeed exist and  
    /// is indeed associated with each animation context target. Transforms that are not  
    /// set are basically NOP elements and have no effect on the overall animation.  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context EnsureDefaultTransforms(this Context target)  
    {  
      foreach (var element in target.Targets)  
      {  
        TransformGroup group = element.RenderTransform as TransformGroup;  
 
        group = new TransformGroup();  
        group.Children.Add(new ScaleTransform());  
        group.Children.Add(new SkewTransform());  
        group.Children.Add(new RotateTransform());  
        group.Children.Add(new TranslateTransform());  
 
        element.RenderTransform = group;  
      } //foreach  
      return target;  
    } //EnsureDefaultTransforms  
 
    /// <summary> 
    /// Include a series of UI elements within an animation context.  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="newElements">List of UI elements to include in the animation</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context With(this Context target, params FrameworkElement[] newElements)  
    {  
      foreach (var elements in newElements)  
      {  
        target.Targets.Add(elements);  
      } //foreach  
      return target;  
    } //With  
 
    /// <summary> 
    /// Exclude a series of UI elements from an animation context.  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="newElements">List of UI elements to exclude from the animation</param> 
    /// <returns>The passed-in animation context</returns> 
    public static Context Without(this Context target, params FrameworkElement[] newElements)  
    {  
      foreach (var elements in newElements)  
      {  
        target.Targets.Remove(elements);  
      } //foreach  
      return target;  
    } //Without  
 
    /// <summary> 
    /// Given one of the weird-looking (but I *think* I understand the syntax)  
    /// property path language (reflection on crack) and a set of arguments,  
    /// set the value of the properties. This type of delayed binding is  
    /// necessary so that the animation sequence can work by setting values  
    /// using the simple 1..N design pattern--the animation simply needs to  
    /// be able to locate and update the properties in question.  
    /// </summary> 
    /// <param name="target">Animation context</param> 
    /// <param name="propertyPath"></param> 
    /// <param name="args">The list of values to set as time-value paris. Presumably this would need to be the set of  
    /// values matching the for loop in the outer-level animation?</param> 
    /// <returns>The passed-in animation context</returns> 
    private static Context SingleProperty(this Context target, string propertyPath, params double[] args)  
    {  
      // had to modify--no LINQ available in my list of .NET assemblies  
      var values = ToList(args);  
 
      if (args.Length % 2 != 0)  
      {  
        throw new InvalidOperationException("Params should come in a time-value pair");  
      } //if  
 
      foreach (var element in target.Targets)  
      {  
        var moveX = new DoubleAnimationUsingKeyFrames();  
        Storyboard.SetTarget(moveX, element);  
        Storyboard.SetTargetProperty(moveX, new PropertyPath(propertyPath));  
 
        for (int i = 0; i < values.Count; i += 2)  
        {  
          moveX.KeyFrames.Add(new SplineDoubleKeyFrame()  
          {  
            KeyTimeKeyTime = KeyTime.FromTimeSpan(TimeSpan.FromSeconds(values[i])),  
            Value = values[i + 1]  
          });  
        } //for  
 
        target.Instance.Children.Add(moveX);  
      } //foreach  
 
      targettarget.StartIndex = target.EndIndex;  
      target.EndIndex += target.Targets.Count;  
 
      return target;  
    } //SingleProperty  
 
    /// <summary> 
    /// A single animation context--which appears to be really a storyboard (which  
    /// makes perfect sense).  
    /// </summary> 
    public class Context  
    {  
      /// <summary> 
      /// Create the context  
      /// </summary> 
      public Context()  
      {  
        // set the storyboard we use  
        this.Instance = new Storyboard()  
        {  
          FillBehaviorFillBehavior = FillBehavior.HoldEnd  
        };  
 
        this.Targets = new System.Collections.Generic.List<FrameworkElement>(4);  
      } //ctor  
 
      /// <summary> 
      /// The starting index for the storyboard--storyboards work as simple for loops  
      /// with dynamic property bindings.  
      /// </summary> 
      public int StartIndex  
      {  
        get;  
        set;  
      } //StartIndex  
 
      /// <summary> 
      /// The ending index for the storyboard--storyboards work as simple for loops  
      /// with dynamic property bindings.  
      /// </summary> 
      public int EndIndex  
      {  
        get;  
        set;  
      } //EndIndex  
 
      /// <summary> 
      /// The list of UI elements affected by the storyboard animation  
      /// </summary> 
      internal System.Collections.Generic.ICollection<FrameworkElement> Targets  
      {  
        get;  
        private set;  
      } //Targets  
 
      /// <summary> 
      /// The storyboard itself  
      /// </summary> 
      internal Storyboard Instance  
      {  
        get;  
        set;  
      } //Instance  
    } //Context  
  } //AnimationExtensions  
} //namespace  
 
using System;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Media;  
using System.Windows.Media.Animation;  
 
namespace Abr.CodeLibrary.Sl.Animation  
{  
  /// <summary> 
  /// Swiped from Telerik; perform a transition from one page to another using  
  /// kewl effects.  
  /// </summary> 
  public class ExampleTransition : ITransition  
  {  
    private Storyboard animation = new Storyboard();  
    private FrameworkElement item1;  
    private FrameworkElement item2;  
    private FrameworkElement mask1;  
    private FrameworkElement mask2;  
    private bool isRunning;  
 
    /// <summary> 
    /// Provides a common event handler for the transition  
    /// </summary> 
    public event EventHandler<TransitionEventArgs> TransitionAnimationCompleted = delegate { };  
 
#if WPF  
        public ExampleTransition(FrameworkElement mask1, FrameworkElement mask2)  
        {  
#else  
    /// <summary> 
    /// Create an example transition--works against a grid as the main container.  
    /// </summary> 
    /// <param name="pageWidth">Should be the ActualWidth of the passed panel (grid)</param> 
    /// <param name="panel">The container that should have page transitioned (from page to page navigation)</param> 
    /// <param name="mask1">Not sure what the masks do, probably the fill color? If so needs  
    /// to be driven from config to match the background of course.</param> 
    /// <param name="mask2">Mask used for (I believe) the navigation on the destination ("to") page</param> 
    public ExampleTransition(double pageWidth, Grid panel, FrameworkElement mask1, FrameworkElement mask2)  
    {  
      this.PageWidth = pageWidth;  
      this.Container = panel;  
#endif  
      this.mask1 = mask1;  
      this.mask2 = mask2;  
    } //ctor  
 
    /// <summary> 
    /// Passed in; should be the panel's ActualWidth from Telerik sample  
    /// </summary> 
    public double PageWidth  
    {  
      get;  
      set;  
    } //PageWidth  
 
    /// <summary> 
    /// The passed on panel--always assumed to be grid (probably fine)  
    /// </summary> 
    public Grid Container  
    {  
      get;  
      set;  
    } //Container  
 
    /// <summary> 
    /// Is the transition animation running? Note that this value *cannot* be  
    /// updated.  
    /// </summary> 
    public bool IsRunning  
    {  
      get  
      {  
        return isRunning;  
      } //get  
#if !WPF  
      set  
      {  
        throw new NotImplementedException();  
      } //set  
#endif  
    } //IsRunning  
 
#if WPF  
    /// <summary> 
    /// WPF only--which I fortunately don't have to worry about this particular Saturday  
    /// morning. I'm sure I will live to regret that sentence--can you say "Azure" guys?  
    /// </summary> 
    /// <param name="mockItem1"></param> 
    /// <param name="container"></param> 
    /// <param name="newPage"></param> 
        public void Begin(FrameworkElement mockItem1, Grid container, FrameworkElement newPage)  
        {  
            this.Container = container;  
            this.PageWidth = container.ActualWidth;  
            this.item1 = mockItem1;  
            this.item2 = newPage;  
 
            this.Container.Children.Add(this.item1);  
 
            var width = PageWidth;  
 
            var scaleFactor = 0.8;  
            var halfShrink = (1.0 - scaleFactor) / 2;  
#else  
    /// <summary> 
    /// The Silverlight version of the animation begin. My goal is to remove the  
    /// Telerik-specific features and implement navigation anyways.  
    /// </summary> 
    /// <param name="page">As originally designed, this is a RadFrame that supports  
    /// a <code>NavigateTo</code> method. Since this base class wants to be independent  
    /// of Telerik trying to avoid this by putting in "just enuf" code to get first-cut  
    /// navigation. Future versions will probably delegate this transitioning to  
    /// derived class--where it is perfectly acceptable to leverage Telerik frame support.</param> 
    public void Begin(FrameworkElement page)  
    {  
      double width = this.PageWidth;  
 
      // the destination  
      this.item2 = page as FrameworkElement;  
 
      // handle empty source (no effects for first time)  
      if (this.Container.Children.Count < 1)  
      {  
        this.Container.Children.Add(this.item2);  
        return;  
      } //if  
 
      // save source  
      thisthis.item1 = this.Container.Children[0] as FrameworkElement;  
 
      // add dest  
      this.Container.Children.Add(this.item2);  
 
      var scaleFactor = 0.8;  
      var page1 = item1 as FrameworkElement;  
 
      var halfShrink = (1.0 - scaleFactor) / 2;  
#endif  
      this.Container.Children.Add(this.mask1);  
      this.Container.Children.Add(this.mask2);  
 
      var scaleDownSpline = new Spline(0.504000008106232, 0.256000012159348, 0.458999991416931, 1);  
      var moveSpline = new Spline(0.247999995946884, 0, 1, 1);  
      var scaleUpSpline = new Spline(0.321000009775162, 0, 0.45100000500679, 1);  
      var spacing = 15.0;  
 
      thisthis.animation = this.item1  
        .Animate()  
        .With(this.mask1)  
          .EnsureDefaultTransforms()  
          .Origin(0, 0.5)  
          .Scale(0, 1, 0.2, 1, 0.7, scaleFactor)  
            .Splines(2, scaleDownSpline)  
          .MoveX(0.7, 0, 1.365, (-width * (scaleFactor - halfShrink)) - spacing, 1.9, (-width * scaleFactor) - spacing)  
            .Splines(1, moveSpline)  
            .Splines(2, scaleUpSpline)  
        .Without(this.item1)  
          .Opacity(0, 0, 0.2, 0, 0.7, 1)  
            .Splines(1, scaleDownSpline)  
        .Animate(this.mask2)  
          .Opacity(1.35, 1, 1.9, 0)  
            .Splines(scaleUpSpline)  
        .With(this.item2)  
          .EnsureDefaultTransforms()  
          .Origin(0.5, 0.5)  
          .Scale(0, scaleFactor, 1.365, scaleFactor, 1.9, 1)  
            .Splines(1, moveSpline)  
            .Splines(2, scaleUpSpline)  
          .MoveX(0.0, ((scaleFactor + halfShrink) * width) + spacing, 0.2, ((scaleFactor + halfShrink) * width) + spacing, 0.7, ((scaleFactor - halfShrink) * width) + spacing, 1.365, 0)  
            .Splines(2, scaleDownSpline)  
            .Splines(3, moveSpline)  
        .Instance;  
 
      this.animation.SpeedRatio = 420.0 / width * 1.5;  
 
      this.isRunning = true;  
#if WPF  
            this.animation.Completed += (sender, e) => 
            {  
                this.TransitionAnimationCompleted(this, new TransitionEventArgs(item2));  
 
                Container.Children.Remove(mask1);  
                Container.Children.Remove(mask2);  
                RemoveVisualBrush();  
                Container.Children.Remove(item1);  
                item1 = null;  
                item2 = null;  
            };  
#else  
      this.animation.Completed += (sender, e) => 
      {  
        this.TransitionAnimationCompleted(this, new TransitionEventArgs(item2));  
 
        // Unregister!  
        Container.Children.Remove(mask1);  
        Container.Children.Remove(mask2);  
        this.Container.Children.Remove(this.item1);  
        item1 = null;  
        item2 = null;  
 
      };  
#endif  
      this.animation.Begin();  
    } //Begin  
 
#if WPF  
        private void RemoveVisualBrush()  
        {  
            var shape = item1 as Shape;  
            if (shape != null)  
            {  
                var visBrush = shape.Fill as VisualBrush;  
                if (visBrush != null)  
                {  
                    visBrush.Visual = null;  
                }  
            }  
        }  
#endif  
 
    /// <summary> 
    /// Stop an outstanding transition  
    /// </summary> 
    public void StopTransition()  
    {  
      // Move to initial state:  
      this.animation.Stop();  
#if WPF  
            this.Container.Children.Remove(this.item1);  
#else  
      this.Container.Children.Remove(this.item1);  
#endif  
      this.Container.Children.Remove(this.mask1);  
      this.Container.Children.Remove(this.mask2);  
      this.item1 = null;  
      this.item2 = null;  
      this.isRunning = false;  
    } //StopTransition  
  } //ExampleTransition  
} //namespace  
 
0
Kaloyan
Telerik team
answered on 26 Nov 2009, 08:29 AM
Hi Manny,

Thank you for sharing this with us. Everything looks good we don't have any comments.

Best wishes,
Kaloyan
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Watch a video on how to optimize your support resource searches and check out more tips on the blogs.
0
Herr
Top achievements
Rank 2
answered on 10 Mar 2010, 10:49 PM
Hi Telerik team,

I try to get this animation work in my Silverlight app. Since I read somewhere on your Website that telerikNavigationFramework is obsolete I try to get it work with the TransionalContentControl and Frame from the silverlight toolkit. I know that this is not an telerik issue but you guys seem to know everything :-)

Thanks for help!

Michael
0
Tina Stancheva
Telerik team
answered on 16 Mar 2010, 01:48 PM
Hi Michael,

I prepared a simple example for you illustrating how you can use RadTransitionControl with Frame control.

Please take a look at it and let me know if it helps or if you need more info.

Regards,
Tina Stancheva
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Herr
Top achievements
Rank 2
answered on 16 Mar 2010, 02:24 PM
Hi Tina,

"shame on me" :-) I could have figured it out myself!!! But I haven't seen the RadTransioningControl yet...
Thanks
Tags
Navigation
Asked by
Henk
Top achievements
Rank 1
Answers by
Miroslav
Telerik team
Henk
Top achievements
Rank 1
Ivan
Telerik team
Joe
Top achievements
Rank 1
Valentin.Stoychev
Telerik team
mohamed
Top achievements
Rank 1
Manny
Top achievements
Rank 1
Kaloyan
Telerik team
Herr
Top achievements
Rank 2
Tina Stancheva
Telerik team
Share this question
or