Here’s how to implement Pinch to Zoom and Pan on an Image Control – using the WP7 toolkit. ( Thanks to Alvaro Peon for this great solution )
Remember allways to add CacheMode=”BitmapCache” to you Image for performance ![]()
XAML:
<Image HorizontalAlignment="Left" Name="photo" Stretch="Uniform" VerticalAlignment="Top" Source="Image.png" CacheMode="BitmapCache"> <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" /> </toolkit:GestureService.GestureListener> </Image>
C# Codebehind:
private Point Center;
private double InitialScale;
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(Image_LargeImage, 0);
Point secondTouch = e.GetPosition(Image_LargeImage, 1);
Center = new Point(firstTouch.X + (secondTouch.X - firstTouch.X) / 2.0, firstTouch.Y + (secondTouch.Y - firstTouch.Y) / 2.0);
}
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;
}
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 = Image_LargeImage.ActualWidth;
double height = Image_LargeImage.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;
}
Advertisement