Yet another blog about...

2009

2008

Home

To content | To menu | To search

Tag - custom

Entries feed - Comments feed

 

CREATE, LAUNCH and CONTROL a WPF animation FROM CODE

7 July 2009

The problem

Sometimes you need to animate your specific object and for this purpose there is the WPF animation.

Here are the prerequireds :

  • The property you want to animate must be a DependencyProperty,
  • The property must so be a part of a DependencyObject,
  • Your object must implement IAnimatable to be able to launch the animation.


The difficulty resides in being able to create an animation, create a storyboard and set the corrects values for the attached properties - TargetName and TargetProperty - on the animation. All of this directly in the code.

You can then control the animation, the usual way than in XAML.

My solution/checklist

Here is how I did it, step by step.

First I make my business object derives from FrameWorkElement. Why ?
Because, this make my object a dependency object. Also, my object will implements IAnimatable ( FrameWorkElement heritate from UIElement which implements IAnimatable). And finally, it gets a NameScope which will be used later.
So here is my object:

public class Puppet: FrameworkElement {    }



Next I will had a DependencyProperty to be animated. Here I animate a value of type Point. I create all the usual things for the dependencyProperty and also add a storyboard (I will always use the same):

public class Puppet: FrameworkElement
{
   public static DependencyProperty ContactMovementProperty =
   DependencyProperty.Register("ContactMovement", typeof(Point), typeof(Puppet));
 
   public Point ContactMovement
   {
       get { return (Point)GetValue(SatelliteNavigator.ContactMovementProperty); }
       set { SetValue(SatelliteNavigator.ContactMovementProperty, value); }
    }
 
    private Storyboard stboard = new Storyboard();
}



Then, let's say I will create and launch the animation directly in the constructor. Here is the code added :

public class()
{
   //Maybe it was running before (if not set in the constructor)
   //stboard.Stop();
 
    double xFinal = 36;
    double yFinal = 36;
    PointAnimation animation = new PointAnimation();
 
    animation.From = ContactMovement;
    animation.To = new Point(xFinal , yFinal );
    animation.Duration = TimeSpan.FromMilliseconds(e.Velocity.Length*7 / deceleration);
    animation.AccelerationRatio = 0f;
    animation.DecelerationRatio = 0.4f;
    String puppetName= "puppet";
 
    NameScope nams = new NameScope();
    NameScope.SetNameScope(this, nams);
    this.RegisterName(puppetName, this);
 
    Storyboard.SetTargetName(animation, puppetName);
    Storyboard.SetTargetProperty(animation, new PropertyPath(Puppet.ContactMovementProperty));
 
    stboard.Children.Add(animation);
    stboard.Begin(this);
 
}


What is done ? First I create the animation with random values for our example.
Then I create a NameScope and set it to our object. Why ? Because it's not created by the runtime for our object and we need one. It will be used by the animation to retrieve the object to animate.

This is done by registering the Puppet object in the namescope and giving the same TargetName of the attachedProperty of the animation(Storyboard.SetTargetName).

Then we clear the children animation of the storyboard (maybe it was not empty) and launch the storyboard by giving it the Puppet (object in which the animated object is).



We can then use the usual methods on storyboard to control the play of the media. For example :

stboard.Stop();


Conclusion

As you can see this is not as easy as writing some XAML lines but it's not impossible !

Any questions ?

kick it on DotNetKicks.com


Shout it


 

Create your VideoPlayer with JavaFX, part one.

9 December 2008

I noticed in this post that the mediaComponent pointed out in the JavaFX demos was not still available and that we will so make our own...

Lets start !

What will we do in our first part ? :

  1. Create our custom node MyMediaComponent
  2. Add the video in our component
  3. Enjoy ourselfs!



Create our custom node: MyMediaComponent

The first thing to do is quite easy : create a new JavaFX class in Nebeans and make it extends the CustomNode class from the javafx.scene package. This class is provided to enable you making your own nodes.

You will then have to ovveride the "create():Node" method :

public override function create():Node{
        return Group{
            content: []
        }
    }

We will add more things in the content when we will build them.
First we will add some var to our class, They will contains some informations about our component :

/** X attribute of our component. */
 public var x : Integer = 0 ;
 /** Y attribute of our component. */
 public var y : Integer = 0 ;
 
/** A description of the video. */
public var vidDescription : String = "" ;
/** The title of the video. */
public var vidTitle : String = "" ;
/** Start volume of the video. */
public var startVolume : Number = 0.5;
/** Do where display the meta informations on the video */
public var showInfoBar : Boolean = true;
/** The url of the video. */
public var mediaURL : String ="" ;
/** The Width in wich where will make the video fit. */
public var vidWith : Integer = 384;
/** The height in wich where will make the video fit. */
public var vidHeight : Integer = 288 ;



Add the video in our component

We will add the video in our component. To add this features we will use three differents Object in the JavaFX API:

  • Media : contains the basic informations about our media, Note that it can be a video or an audio media...
  • MediaPlayer: this object is used to perform the differents actions on our video; play/pause. This component also contains the informations about the status of the current video: playing/paused/buffering, etc ... We give it the media.
  • MediaView: this object is the node in which the video is displayed. We give it the mediaPlayer.



Lets add it in our class and use the differents var we created just before :

var media:Media = Media{
        source: mediaURL
    };
    var mediaPlayer: MediaPlayer = MediaPlayer{
        media:media
        autoPlay:true
    };
 
    var mediaView : MediaView = MediaView{
        x:x
        y:y
        mediaPlayer: bind mediaPlayer
        fitHeight:vidHeight
        fitWidth:vidWith
      };

The autoPlay attribute tells that the video is played as soon as it can be by the player (when enough data is available when buffered).


Now that we have created the different component we will add the mediaView in the group returned by our create() function:

public override function create():Node{
        return Group{
            content: [mediaView ]
        }
    }


Now by adding our component in your application you will display the video and play it. This is a first step in the birth of our videoComponent: Video player, results of part one.


In the next part you will learn how to display the informations on the video currently played when hovering the video and how to add some triggers (play/pause the video by clicking on it).

+++