Implementing Pinch to Zoom images in WP7
March 10th, 2011 § 4 Comments
My friends at Crazy Mayans and I knew from the start that our app needed pinch to zoom but didn’t have enough time to do it for v1.0. When we started looking at this there were so many people saying how to do it but we found all solutions rather lacking. The interesting thing was that the Silverlight Toolkit is the solution but they have no documentation!
Here is how we implemented it (we did not include rotation nor inertia), by no means this is the perfect solution but it worked for us:
1. Install the Silverlight Toolkit
2. Add the reference dll to your project
3. Add the reference to your page class xml
xmlns:toolkit=”clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit”
4. Add the GestureListener and Transformation to your photo (not you have to create the methods for those events)
<Image HorizontalAlignment=”Left” Name=”photo” Stretch=”Uniform” VerticalAlignment=”Top” Source=”MyPhoto.png”>
<Image.RenderTransform>
<CompositeTransform x:Name=”ImageTransformation” ScaleX=”1″ ScaleY=”1″ />
</Image.RenderTransform>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener PinchStarted=”GestureListener_PinchStarted” PinchDelta=”OnPinchDelta” DragDelta=”Image_DragDelta” Tap=”photo_Tap”/>
</toolkit:GestureService.GestureListener>
</Image>
5. Declare a global private Point center and a double initialScale variables
6. On pinch start method
private void GestureListener_PinchStarted(object sender, PinchStartedGestureEventArgs e)
{
// store the initial rotation angle and scaling
initialScale = ImageTransformation.ScaleX;
// calculate the center for the zooming
Point firstTouch = e.GetPosition(photo, 0);
Point secondTouch = e.GetPosition(photo, 1);
center = new Point(firstTouch.X + (secondTouch.X – firstTouch.X) / 2.0,
firstTouch.Y + (secondTouch.Y – firstTouch.Y) / 2.0);
7.
private void OnPinchDelta(object sender, PinchGestureEventArgs e)
{
// if its less that the original size or more than 4x then don’t apply
if (initialScale * e.DistanceRatio > 4 || (initialScale != 1 && e.DistanceRatio == 1) || initialScale * e.DistanceRatio < 1)
return;
// if its original size then center it back
if (e.DistanceRatio <= 1.08)
{
ImageTransformation.CenterY = 0;
ImageTransformation.CenterY = 0;
ImageTransformation.TranslateX = 0;
ImageTransformation.TranslateY = 0;
}
ImageTransformation.CenterX = center.X;
ImageTransformation.CenterY = center.Y;
// update the rotation and scaling
if (this.Orientation == PageOrientation.Landscape)
{
// when in landscape we need to zoom faster, if not it looks choppy
ImageTransformation.ScaleX = initialScale * (1+(e.DistanceRatio-1)*2);
}
else
{
ImageTransformation.ScaleX = initialScale * e.DistanceRatio;
}
ImageTransformation.ScaleY = ImageTransformation.ScaleX;
}
8. Implement drag
private void Image_DragDelta(object sender, DragDeltaGestureEventArgs e)
{
// if is not touch enabled or the scale is different than 1 then don’t allow moving
if (ImageTransformation.ScaleX <= 1.1)
return;
double centerX = ImageTransformation.CenterX;
double centerY = ImageTransformation.CenterY;
double translateX = ImageTransformation.TranslateX;
double translateY = ImageTransformation.TranslateY;
double scale = ImageTransformation.ScaleX;
double width = photo.ActualWidth;
double height = photo.ActualHeight;
// verify limits to not allow the image to get out of area
if (centerX – scale * centerX + translateX + e.HorizontalChange < 0 &&
centerX + scale * (width – centerX) + translateX + e.HorizontalChange > width)
{
ImageTransformation.TranslateX += e.HorizontalChange;
}
if (centerY – scale * centerY + translateY + e.VerticalChange < 0 &&
centerY + scale * (height – centerY) + translateY + e.VerticalChange > height)
{
ImageTransformation.TranslateY += e.VerticalChange;
}
return;
}
9. Test! each app is different make sure it behaves as you want
We hope this helps
Not workin’ for me,, perhaps I am doing something terribly wrong?
Name cannot begin with the ’1′ character, hexadecimal value 0×31. Line 28, position 89. J:\Users\Admin\Documents\Visual Studio 2010\Projects\—\—\pageViewImage.xaml
Expected class, delegate, enum, interface, or struct J:\Users\Admin\Documents\Visual Studio 2010\Projects\—\—\pageViewImage.xaml.cs
COMPLEET PAGE CODE:
.cs:
http://plaatscode.be/141101/
.xaml:
http://plaatscode.be/141102/
Fixed the errors, but nothing seems to happing in the emulator when I tap the image
I could not find a way to test in on the emulator so I had to deploy it to the phone and test it there.
[...] on an Image Control – using the WP7 toolkit. ( Thanks to Alvaro Peon for this great solution ( http://alvaropeon.wordpress.com/2011/03/10/implementing-pinch-to-zoom-images-in-wp7/ ) [...]