Frank La Vigne

Fear and Loathing in .NET

MVP Logo
Tablet PC MVP

Social Networks

Subscription Options

Add to Google

Subscribe in Bloglines

My Links


Post Categories

Archives

Image Galleries

Cached @ 9/3/2010 2:32:40 AMControl ASP.skins_marvin3_controls_archivelinks_ascx

GamerTag

Dev Community Events

Blog Stats

Cached @ 9/3/2010 2:32:40 AMControl ASP.skins_marvin3_controls_blogstats_ascx  

News


Blog Roll

Favorite Sites

Gadget Blogs

Tablet PC Links

Cached @ 9/3/2010 2:32:40 AMControl ASP.skins_marvin3_controls_categorydisplay_ascx

Christmas is Going to the Dogs: Behind the Scenes (Part 2: Structure and Code)

I know in Part 1 posted Tuesday, I said that I'd be back Wednesday to explain more of "Christmas is Going to the Dogs" card.  Needless to say that this is the week before Christmas and thigns have been a little hectic.

With the apology out of the way ;), let's get down to business

About the Project

Here are answers to some frequently asked questions about the card:

  1. it's done with Silverlight 1.0.
  2. It's not a movie, it's a series of photos that are animated to the music.
  3. I used *both* Expression Blend and Visual Studio 2008.
  4. Due to limitations with Blend, I had to edit some XAML by hand.
  5. Sometimes, the intro music doesn't play, sometimes it does. This may be Alpha bits interfering with the playback of 1.0 animation. (anyone have more information on this?)
  6. It took only a few late nights.
  7. My previous experience with Flash both helped me and hurt me. :)

Backgrounder

Given my history with Flash-based animations, a lot of what I'll discuss are the differences and pain points between Flash and Silverlight.

To paraphrase Rob Zelt's presentation at Silverlight DevCamp DC, Flash and Silverlight were created at different times in the life of the Internet, built to serve different needs, and have different design goals.

Flash has been around a while, ten years to be exact and the Internet back then was a different place.  Flash was primarily designed to provide a bandwidth efficient means of providing animation and basic interactivity.

Like Silverlight/WPF, Flash relies heavily on vector graphics.  Vector graphics had a much smaller bandwidth footprint and, in the days of 28.8 kbps modems, this mattered. 

Flash has changed and evolved over time, but at its core, it's still a way to provide animation with interactivity tacked on to it.

Silverlight is really the other approach: a way to provide interactivity that can kick off animations.

More on that later.

Structure

In Part 1, I mentioned the three canvases: one for the Intro, the Feature Presentation, and the credits.

canvases

And you'll see that my naming conventions are consistent:

  1. cvsInto
  2. cvsFeaturePresentation
  3. cvsCredits

Blend has no concept of "Scenes," like Flash does.  Scenes are like clips of a movie. Scenes can be treated as an single unit all on its own and/or arranged around other scenes. Using ActionScript, you can control which scenes play and in which order. 

Scenes are a nice abstraction, as a complex movie will have a lot of parts.   Scenes let you break down a complicated animation into manageable parts.  After a dozen or so elements, timelines can get unruly. 

Flash makes the assumption that Time is the primary mover.  The timeline kicks off whether you like it or not.  Stopping the timeline requires scripting.

Silverlight, on the other hand, runs an event-based very familiar to WinForm, WPF, and ASP.NET developers. This is a subtle, but important difference.

Unless you set up a trigger or tell a timeline to start via code, nothing happens.  Notice that I used the phrase "a timeline."  Timelines are officially known as StoryBoards and you can have any number of them in a given Silverlight animation.

Thinking in Flash, but Working in Blend

The CBS Christmas Special intro homage animation was the first piece I tackled. In my mind's eye, I could immediately picture how to create the animation in Flash.

I create a text object, write the word "Special" and convert it to a library object. I animate the first one, then copy and paste the frame on subsequent layers and offset each layer by a frame or two.

Flash has a fixed Frames per Second property in a given animation. If you want tenth of a second accuracy, you need to change your animation to 10 frames per second or some other number that ten divides into ten nicely.

Silverlight has no fixed framerate, it automatically upgrades or downgrades the framerate based on the computer it's running on.  At first, I wasn't keen on the idea, but after seeing Silverlight animations gracefully perform on computers with different processors, I'm sold.

Even though the the intro runs for five seconds, I learned quite a bit creating it.

Looking at the finished product in Blend, the Special storyboard looks tame, but I edited the XAML by hand to get the precision I wanted.

special_storyboard

I have eight TextBlock elements, each contains the word "SPECIAL" in different colors. (See the YouTube video for reference.)

The opening tag of the Storyboard defines the Name of the storyboard and an event listener for the Completed event.

In the interest of brevity, I'll only show part of the XAML here:

    BeginTime="00:00:0.5" Storyboard.TargetName="textBlock1" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
       
        KeyTime="00:00:01.75"
Value="-89.514"/>
   
    BeginTime="00:00:0.6" Storyboard.TargetName="textBlock2" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
       
        KeyTime="00:00:01.85" Value="-89.514"/>
   

In red you'll see the start time for the given Animation and in blue the end times.  You'll see that they are one tenth of a second apart.  Imagine that repeated six more times. :)

When the timeline completes, it fires an event, which I have this method (function in Javascript) listening for:

function SpecialAnim1_Completed(sender, eventArgs)
{
    setTimeout("StartFeaturePresentation()", 2000);

}

This code will wait two seconds and call the StartFeaturePresentation method, which calls four other methods (see below).

Since there are no scenes, I treat Canvases as if they were scenes, but I have to do a little extra legwork to make that happen.  Specifically, I manually hide and show the canvases via code.

This post continues on the other side of this code block.

function StartFeaturePresentation()
{
    HideIntroCanvas();
    ShowFeatureCanvas();  
    StartFeatureMusic();
    StartFeatureTimeLine();

}

function HideIntroCanvas()
{
    var controlContent = _control.content;

    controlContent.findName("cvsIntro").Visibility="Collapsed";

}

function ShowFeatureCanvas()
{
    var controlContent = _control.content;
    var FeatureCanvas = controlContent.findName("cvsFeaturePresentation")

    FeatureCanvas.Visibility="Visible";

}

function StartFeatureTimeLine()
{
    var controlContent = _control.content;

    controlContent.findName("SnowFall").Begin();

}

function StartFeatureMusic()
{
    var controlContent = _control.content;
    var FeatureCanvas = controlContent.findName("cvsFeaturePresentation")
    var mediaPlayer = FeatureCanvas.findName("mediaFeatureMusic");
    mediaPlayer.Play();

}

After the Intro Canvas is hidden and the Feature Presentation is visible, I kick off the timeline (in red) and play the music (in orange).

There currently is no way to synch music to a timeline.

Flash developers will recoil in horror when they see this: we're leaving the synch of the animation and music to chance: trusting the Silverlight runtime to keep everything in step.

But, if you watch the animation you'll see it works out quite nicely and the honor system works out.  The animation will actually drop frames to keep up if it happens to get out of synch.

By far, the biggest pain point of Silverlight 1.0 development is Javascript.  Loosely typed languages are hard to work with.  The intellisense in VS2008 works on the core Javascipt and DOM objects, not Silverlight objects.

There's no way to address an object in XAML in Silverlight 1.0 with a syntax like:

root.cvsFeaturePresentation.mediaFeatureMusic.Play();

Hence the liberal use of FindName methods, which is annoying to say the least. 

Thankfully, this nonsense goes away in Silverlight 1.1/2.0.

Coming up soon Part 3.

 

posted on Friday, December 21, 2007 12:55 PM

============ Debug Build ============
Dottext Version: 0.95.2004.102
Machine Name: IIS07902
.NET Version: 2.0.50727.3053
No User
============ Debug Build ============