Several weeks back I had posted a simulation of the Genie effect that you see in Mac OSX. Ofcourse it was created using the Windows Presentation Foundation ;) However the effect could only be used in that specific demo. There was no way for example to use it in my other projects, which were also desperately asking for some cool animations. Since then I went through a couple of iterations and made the Genie effect into a reusable animation. This was possible because the WPF animation system makes it pretty easy to create Custom animations. So what I have now is a class called GenieAnimation that can be used directly in XAML.
Here is an example of using the GenieAnimation inside a Storyboard:
<Storyboard x:Key="GenieAnim"> <local:GenieAnimation Storyboard.TargetName="SlidingScreen" Storyboard.TargetProperty="Geometry.(MeshGeometry3D.Positions)" AspectRatio="1.25" HorizontalPoints="25" VerticalPoints="25" EffectType="IntoLamp" LeftPoint2="0.75,0.333,0" LeftPoint4="1,1,0" RightPoint3="0.25,0.667,0" Duration="0:0:1" AccelerationRatio="0.5" DecelerationRatio="0.5" /> </Storyboard>
Note that there are some extra properties like AspectRatio, HorizontalPoints, VerticalPoints, EffectType, etc. These are custom dependency properties defined on the GenieAnimation class. Also note that the Storyboard.TargetProperty for the animation is of type System.Windows.Media.Media3D.Point3DCollection. If you look under the WPF namespaces then you would not find any animation defined for this type. So I had to create an abstract Point3DCollectionAnimationBase class that sets the TargetPropertyType to Point3DCollection. This is as per the SDK article on custom animations. The GenieAnimation then derives from Point3DCollectionAnimationBase.
What I really like about the GenieAnimation is that I get lot of cool stuff for Free, just for being a citizen of the WPF animation system. This includes features like AutoReverse, RepeatBehavior, AccelerationRatio, DecelerationRatio, etc. To do these things in my previous implementation would have required lot of extra code!
Using the GenieAnimation
To make use of the properties that control the GenieAnimation, you will have to know a little bit about how the animation works. I have already spoken about it in my earlier post. But let me go over it again. The GenieAnimation works over the MeshGeometry3D.Positions property (type: Point3DCollection). In every time interval the animation updates the mesh positions and transforming the mesh from its rectangular form to the more curvaceous genie-form. The genie is created by two beziers, one on the left and one on the right. The left bezier can be specified by the 4 control points: LeftPoint1, LeftPoint2, LeftPoint3, LeftPoint4. The same works for the right bezier: RightPoint[1-4].
Since the Genie is really a mesh, you also need to tell me how smooth a mesh you want to use. This is specified using the HorizontalPoints and VerticalPoints property. The value 25 works very well for these two properties. The AspectRatio property is a technical detail, that I really want to hide. This is used when creating the mesh positions. The value for this property depends on the size of your Viewport3D object, so in most cases you would just use Viewport3D.ActualWidth / Viewport3D.ActualHeight as your AspectRatio.
Out of all the properties, my favorite is the EffectType, which can be either IntoLamp or OutOfLamp. IntoLamp creates a suction effect and sucks in the mesh, whereas OutOfLamp releases the genie out of the lamp ;)
A Video demonstration
Yes! a video of the GenieAnimation. In the video I modify various properties of the GenieAnimation and then run the app. So you will see me switching between Visual Studio and the app window.