There's a site online I've seen a few times through the years, and always thought it was cool. It shows a photo of Seattle's waterfront taken in 1907, and there's a slider you can move to see it in 2002. I emailed the creator of the site, Alan Taylor, and got permission to do a Silverlight version, which can be seen here.

The idea behind the Silverlight approach to the application is pretty straightforward - create both image layers, a clipping path, and a draggable handle. As the handle is manipulated, adjust the clipping path accordingly.

Along those lines, this is what my XAML looks like:

 
<Canvas x:Name="LayoutRoot" Background="#FF000000" Width="850" Height="243">
    	<Image Height="173" x:Name="_2002" Width="850" Canvas.Top="18"
          Source="sea_wft_850_2002.jpg"
          Stretch="None"/>
    	<Canvas Height="173" Width="850" Canvas.Top="18" x:Name="Then">
    	<Image Height="173" x:Name="_1907" Width="850" Source="sea_wft_850_1907.jpg"
             Stretch="None"/>
    	    <Canvas.Clip>
                <PathGeometry>
                    <PathFigure IsClosed="true">
                        <LineSegment x:Name="PathTopLeft" Point="0,0"/>
                        <LineSegment x:Name="PathTopRight" Point="8,0"/>
                        <LineSegment x:Name="PathBottomRight" Point="8,173"/>
                        <LineSegment x:Name="PathBottomLeft" Point="0,173"/>
                    </PathFigure>
                </PathGeometry>
            </Canvas.Clip>
	</Canvas>
    	<Image Height="243" x:Name="Handle" Width="16" Source="glass3.png" Stretch="None"
          Canvas.Top="-2"/>
</Canvas>

Notice the <Canvas.Clip> code, which creates a clipping path out of a path constructed from line segments. In this case, it's a rectangle.

The code-behind starts out by declaring the variables used for dragging, as well as two points - one to store the top right of the clipping path, and the other to store the bottom right. The left side of the clipping region does not move.

 
private bool IsMouseCaptured;
private Point MousePosition;
private Point TopRightPoint = new Point();
private Point BottomRightPoint = new Point();
 

Inside the Page() constructor, I set the default Y values for my point objects, and create a few event listeners. The "Handle" object is the handle that the user manipulates to change the view.

 
TopRightPoint.Y = 0;
BottomRightPoint.Y = 173;
 
Handle.MouseLeftButtonDown += new MouseButtonEventHandler(Handle_MouseLeftButtonDown);
Handle.MouseLeftButtonUp += new MouseButtonEventHandler(Handle_MouseLeftButtonUp);
Handle.MouseMove += new MouseEventHandler(Handle_MouseMove);
 

The mouse up and mouse down handlers contain pretty standard drag and drop code, as does the mouse move handler. However, the mouse move code was also augmented with the code that updates the clipping path. The following code shows how that is done. It starts out by checking to see if the handle has reached either end of it's range. If it's within range, the right side of the clipping path is calculated based on the position of the handle. Then the handle position is updated, as are the clipping path points.

 
if (NewLeft >= 0 && NewLeft <= LayoutRoot.Width - Handle.Width)
{
    TopRightPoint.X = BottomRightPoint.X = NewLeft + 8;
    Item.SetValue(Canvas.LeftProperty, NewLeft);
    PathTopRight.Point = new Point(NewLeft + 8, 0);
    PathBottomRight.Point = new Point(NewLeft + 8, 173);
}
 

That's all there is to it! One of the things I like about implementing this technique in Silverlight is that you instantly have a version that works cross-platform, cross-browser. No need to worry about the nuances between browsers. You'll notice that the original version does not work in Firefox, for example. When we're building applications at work, we always test in IE6, IE7, IE8, FF2, FF3, and on the Mac, and I can't recall the Silverlight bits of our projects ever having and consistency or look and feel issues like the HTML portions of pages often do, due to styling issues and what not.

If you want to see the final project, you can download the code here.

I've had some time to experiment more with DeepZoom, and was able to provide the Expression Composer team with one of the projects that was causing me problems.

If you nest enough images, the images become "small" enough that the encoder doesn't know what to do (and in my case, did nothing). I have found that this seems to occur for me once I get to about 4 images or so, but only if they are overlapping. If I scale the images and position them next to one another, Composer will export the files as expected.

This led to a different problem, however. When placing the images next to one another so that each is smaller than the previous one, by the time I'm zoomed in on the last of 9 images, it's blurry and illegible. This one seems to be more of an issue with the rendering engine, because the JPG the multiscale image control is using looks great. It *looks* like you're zoomed way in on an image, but it's not resolving to the smooth version.

These kinds of issues are to be expected with pre-release software, of course. I'm really excited about this feature though. There's a ton of possibility there - I'm looking forward to updates as they become available!

Like everyone else, I was deeply interested in the DeepZoom feature that introduced at MIX.

I spent some time playing with it, and at the moment, it looks to have some limitations. Granted, it's a preview release (Expression Composer), and I'm probably not doing the software any favors by choking it up with a half-dozen or so high-res photos, but it seems really hit or miss. I can lay out all of my photos in the main display, export it, and it works fine.

When I start scaling the images down and positioning them in order to create the "zoom" effect, once I get past 3 or 4 images, the software just stops updating the output file. It *says* it's exporting, but it doesn't actually seem to *do* anything.

Drag/Resize Images

A compact client side script that gives a feeling like going through an old shoebox of photos - you see the corner of an old memory peeking out from beneath the others, lovingly grab it from the pile, and hold it up to take a closer look.

View    Download (471K ZIP)