Wednesday, April 2, 2008

Dissecting Hard Rock Memorabilia and Silverlight Deep Zoom - Part 7

One of the readers asked me if I could post code to center the clicked image on the screen. So here goes...

Update Oct 14, 2008: Removed the example from this post to reduce load time of this page. Please use the example from this post, DeepZoom sample ported to Silverlight 2 Beta 2, to try the functionality.



The example above centers and zooms the clicked image.

Here is the code

msi.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e)
{
if (mouseButtonPressed && !dragInProgress)
{
Point p = this.msi.ElementToLogicalPoint(e.GetPosition(this.msi));
int subImageIndex = SubImageHitTest(p);
if (subImageIndex >= 0)
DisplaySubImageCentered(subImageIndex);

bool shiftDown = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;
if (shiftDown) Zoom(0.5, e.GetPosition(this.msi));
else Zoom(2.0, e.GetPosition(this.msi));
}
mouseButtonPressed = false;
dragInProgress = false;
};


void DisplaySubImageCentered(int indexSubImage)
{
if (indexSubImage < 0 || indexSubImage >= msi.SubImages.Count)
return;

Rect subImageRect = GetSubImageRect(indexSubImage);
double msiAspectRatio = msi.ActualWidth / msi.ActualHeight;

Point newOrigin = new Point(subImageRect.X - (msi.ViewportWidth / 2) + (subImageRect.Width / 2),
subImageRect.Y - ((msi.ViewportWidth / msiAspectRatio) / 2) + (subImageRect.Height / 2));

msi.ViewportOrigin = newOrigin;
}

int SubImageHitTest(Point p)
{
for (int i=0; i<msi.SubImages.Count; i++) {
Rect subImageRect = GetSubImageRect(i);
if (subImageRect.Contains(p))
return i;
}

return -1;
}

Rect GetSubImageRect(int indexSubImage)
{
if (indexSubImage < 0 || indexSubImage >= msi.SubImages.Count)
return Rect.Empty;

MultiScaleSubImage subImage = msi.SubImages[indexSubImage];

double scaleBy = 1 / subImage.ViewportWidth;
return new Rect(-subImage.ViewportOrigin.X * scaleBy, -subImage.ViewportOrigin.Y * scaleBy,
1 * scaleBy, (1 / subImage.AspectRatio) * scaleBy);
}

3 comments:

Jeremy said...

Awesome, I look forward to diving into these posts. I really appreciate you taking the time to share with us your experience on this project!

Marco Silva said...

Hello Wilfred, My thanks for your time and help, with the code You shared I could proceed with my project, your help was priceless.
I think your blog is a reference for any one that is starting to develop something in Deep Zoom. Many thanks and congratulations on your blog and work!

jwize said...

Any Chance at getting the rest of the links about dissecting the hard rock application?

It would also be interesting if you were the Marco Silva I used to play pool with in vancouver.

Jaime