Showing posts with label WPF Graphics. Show all posts
Showing posts with label WPF Graphics. Show all posts

Saturday, August 22, 2009

[2009.08.22] Basic Per Frame Animation in WPF

As I was going through the WPF Animation Documentation, I noticed something about Per Frame animation but there is little written on it. From what I saw, I was reminded of Jeff Paries's Foundation Silverlight 2 Animation. The book did a great job of showing the power of animating in Silverlight and I wanted to port those concepts to WPF. However, it did not go as smoothly as I wanted. But after seeing how per frame animation works, I think I am on the right track.

While custom and key frame animations gives the user a lot of power to animate objects, for some scenarios, a closer grain control over the animation may be needed. Basically, you have a container (Canvas) of objects you wan to animate (Ellipse). What you do is call the static Rendering event of the CompositionTarget class on the container. This class represents the display surface that the application is being drawn on. The event is called once per frame. Each time that WPF marshals the persisted rendering data in the visual tree across to the composition tree, your event handler method is called (from documentation).

You can think of this as calling the Completed event of a repeating Storyboard. Inside of the Rendering method, you update the properties of the object you want animated and when the event is fired again, your changes will be reflected as such.

Currently, I don't know a whole lot about the CompositionTarget class. It is small but it uses another class that is not documented called MediaContext. Actually, there isn't a whole lot of documentation to go around anyway. This type of animation puts you more into visual layer animations.

I have added some basic code that bounces a ball on the screen using Per Frame animation. It is pretty straight forward and I will build on this in the future.

  1: <Window x:Class="Wpf_OnRenderAni03.Window1"
  2:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4:     Title="Window1" Height="300" Width="300">
  5:     <Canvas Name="layoutRoot" >
  6:         <Ellipse Name="myBall" Width="30" Height="30"
  7:                  Canvas.Left="10" Canvas.Top="10">
  8:             <Ellipse.Fill>
  9:                 <RadialGradientBrush GradientOrigin="0.666,0.093" 
 10:                                      RadiusX="0.547" RadiusY="0.547" 
 11:                                      Center="0.5,0.47">
 12:                     <GradientStop Color="#DBFCF8F8"/>
 13:                     <GradientStop Color="#E40C0C0C" Offset="0.87"/>
 14:                 </RadialGradientBrush>
 15:             </Ellipse.Fill>
 16:         </Ellipse>
 17:     </Canvas>
 18: </Window>

  1: using System;
  2: using System.Windows;
  3: using System.Windows.Controls;
  4: using System.Windows.Media;
  5: 
  6: namespace Wpf_OnRenderAni03
  7: {
  8:     public partial class Window1 : Window
  9:     {
 10:         // vector to add 'speed' to the X,Y 
 11:         //  component of the position of the ball
 12:         private Vector speed = new Vector(2, 3);
 13:         private Vector ballPosition = new Vector();
 14: 
 15:         public Window1()
 16:         {
 17:             InitializeComponent();
 18: 
 19:             // handle the motion and update the
 20:             //  position of the ball here
 21:             CompositionTarget.Rendering += MoveBall;
 22:         }
 23: 
 24:         void MoveBall(object sender, EventArgs e)
 25:         {
 26: 
 27:             // get the position of the ball
 28:             this.ballPosition.X = (Double)(this.myBall.GetValue(Canvas.LeftProperty));
 29:             this.ballPosition.Y = (Double)(this.myBall.GetValue(Canvas.TopProperty));
 30: 
 31:             // test to see if the ball has gone beyond the
 32:             //  bounds of the application
 33:             // as soon as it hits one of the edges, reverse
 34:             //  the speed component to basically bounce the
 35:             //  ball off the edges
 36:             // NOTE: no test has been done if the ball hit
 37:             //  any of the 4 corners where the ball is touching
 38:             //  both the horizontal and vertical edges of the app
 39:             // test left and right
 40:             if (this.ballPosition.X <= 0 || this.ballPosition.X > 
 41:                 this.layoutRoot.ActualWidth - this.myBall.Width)
 42:                 this.speed.X *= -1;
 43:             // test top and bottom
 44:             if (this.ballPosition.Y <=0 || this.ballPosition.Y > 
 45:                 this.layoutRoot.ActualHeight - this.myBall.Height)
 46:             {
 47:                 this.speed.Y *= -1;
 48:             }
 49: 
 50:             // update the ball position using the speed
 51:             Canvas.SetLeft(this.myBall, ballPosition.X + speed.X);
 52:             Canvas.SetTop(this.myBall, ballPosition.Y + speed.Y);
 53:         }
 54:     }
 55: }

Fig. 1 shows a gif animation of the bouncing ball. Pardon the quality of it all :=)

[2009.08.22].Basic.Per.Frame.Animation


Fig. 1. Basic bouncing ball using per frame animation

Tuesday, January 6, 2009

[2009.01.06] Learn to Write in WPF

I took on this little project at my sister's suggestion given that she is an Occupational Therapist and also because it gave me a chance to become more proficient with Expression Blend. I am far from being a graphic designer or just designer in any shape or form and I hope to improve on what I have here in version 2.0 as I already have some ideas.

This program is basically to help kids, especially autistic kids, learn how to write the letters of the alphabet. It is designed to be interactive, so each button click will trigger an animation which follows a ball that guides the user on how to form the particular letter clicked. I used Arial font for this initial project and will look into others on the next round.

Expression Blend was used heavily here and very little code was written. Actually the only code is for the menu items, to trigger the About box and to exit the program from the menu. Everything else was done in Blend.

First off, I made the main window a fixed size (1022 x 660) to accommodate the letters and it cannot be resized, or else the animation will get messed up. This is something I intend to address in the next iteration.

[2009.01.06].01.learnwriting.mainWindow
Fig.1 LearnWriting main window

The buttons are template driven to be custom to this application and there are MouseIn and MouseOut animations. Two templates were used for upper case and lower case, where the animation is just a different color. The Click event also uses template bindings to change the look of the buttons.

[2009.01.06].02.mousein
Fig.2 MouseIn animations

Once a button is clicked, a little yellow ball traces the shape of the letter and the letter color will change from black to red back to black.

[2009.01.06].03.letter.tracing
Fig.4 Letter tracing

NOTE: You may need to download and install the Microsoft .NET 3.0 or 3.5 to get this program to work. Here are links to each version (I'd recommend you get the latest, which as of this writing is 3.5 SP1):
[1] Microsoft .NET Framework 3.0 Redistributable Package
[2] Microsoft .NET Framework 3.5 SP1 Full Install Package

Technologies used: .NET 3.5 SP1, Expression Blend 2 SP1, Visual Studio 2008 SP1, WPF 3.5 SP1

Download Links:

Get the LearnToWrite executable (19Kb, zip)
Get the LearnWriting source files (556Kb, zip)

Wednesday, June 25, 2008

[2008.06.25] Custom Coordinates in WPF

In the 2D graphics world, WPF uses the top-left corner of the window as its point of origin (0,0). However, you can easily change the coordinate system to match your needs, such as switching to the Cartesian Coordinate system. Doing this simply requires using Transformations to reposition all the necessary elements.

The code below demonstrates how this is accomplished and the image shows what happens as each transformation is applied to the Canvas element.

 

<Border Grid.Row="2" Grid.Column="0" Margin="5" CornerRadius="4"

       Height="100" Width="100"

       BorderBrush="Black" BorderThickness="1">

    <Canvas Height="90" Width="90" Background="LightGreen">

        <Line Stroke="Red" StrokeThickness="1"

            X1="0" Y1="0" X2="50" Y2="50" />

        <Canvas.RenderTransform>

            <TransformGroup>

                <ScaleTransform ScaleY="-1" />

                <TranslateTransform Y="90" />

            </TransformGroup>

        </Canvas.RenderTransform>

    </Canvas>

</Border>

[2008.06.25].Custom.Coordinates.in.WPF

Tuesday, February 12, 2008

[2008.02.12] WPF Reflection Effect

I was just playing around with WPF and Expression Blend and decided to throw together a quick demo of what you can accomplish in WPF with very little or no C# at all! This is a reflection effect of an anime music video. Of course, since it's just a quick demo, I hard coded the name video file. However, the source code is short and easy to understand, and you can change it to suit your needs. The main concepts illustrated here are Transformations, Visual Brushes and Gradients. Here are some images of what it will look like.

[2008.02.12].01.wpfReflection
Fig.1 WPF reflection 1

[2008.02.12].02.wpfReflection
Fig.2 WPF reflection 2

See/get the code