Dragging, Easing & Inertia
Let's start putting together what we've been learning into a larger sample that
works with raster images as well. Here is the Flash movie we will be reproducing
in Silverlight:
We coded this example in ActionScript 1.0, keeping it light and simple for all levels
of Flash designers. More advanced Flash programmers would no doubt choose to encapsulate
the logic into a few classes, as we will do in our Silverlight rebuild later.
Here is the ActionScript 1.0 that creates the panels and loads the images dynamically:
Notice that Line 1 creates the variable we will use to hold a reference to which
panel is currently being dragged. Line 9 adds an onMouseMove() handler to
the stage that will determine if the drag object needs to be told where to go, and
Lines 30 through 32 add the eventHandlers for each of the panels. You may also notice
that we do not want to do the typical startDrag() call, since we want to
have a more easing behavior in our drag as well as allow us to throw the tiles if
we want. Therefore, we're building our own drag and throw logic. Here are the handler
definitions that come next and finish our script:
The two lines of code that handle the easing are Lines 70 and 71 and the algorithm
is one of the most versatile around, where you want to be minus where you are times
a percentage. Add this result to where you currently are and repeat per
frame. You will see algorithm like this in various forms for all types of properties
over the next several lessons and it's one of the most used algorithms in the toolbox.
Although not necessary for drag, Lines 76 through 79 add velocity and friction to
keep the panel moving if the user decides to throw it instead of simply dragging
it.
Rebuilding the Project in Silverlight
After we create our Silverlight project and change the LayoutRoot tag in
Page.xaml to a Canvas, we also design the background like we want it and
add a Loaded handler to our User Control tag. For this project, we will also
add a new User Control to the solution called Panel.xaml and do the
same modifications to it as well. Here are what the two XAML files should look like
when we're done:
The most important thing to note is that we have added an Image tag to Panel.xaml
at Line 8 and named it image. Since we already know the sizes of the pictures
we will be using for this project, we can move the Image holder to the left and
up to center it around the registration point of this User Control.
Page.xaml.cs handles the dynamic loading of each Panel.xaml user control
as well as hooking up their press and release behavior for dragging. Here is what
the Page.xaml.cs code behind file looks like:
Since each Panel.xaml has its own Image tag, each User Control can
be in charge of loading its own graphic. Each Panel.xaml also has its own
Storyboard object for easing it toward its targetX and targetY values
that Page.xaml sets while dragging. Also note that since we will be dealing
with images, Line 12 needs to add a using reference to System.Windows.Media.Imaging.
Here is what Panel.xaml.cs looks like when done:
The line that handles the actual image loading is Line 53. For this to work, the
images (orchid0.png through orchid5.png) were added to the Silverlight
Project and by default, had their Build Action property set to Resource.
This copies the pictures into the Lesson04_a.xap, so if you look for them
in the ClientBin, you won't find them. However, you can still reference them
as a relative url by name as shown in Line 53.
And finally, here is what our Silverlight rebuild looks like:
In this lesson, the Silverlight project loaded images dynamically, but the images
were already baked into our XAP file. But what if you want to load the images from
a different URL? We will learn this next.