I found this Pinch-to-zoom example at http://forums.create.msdn.com
Here is the xaml:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="Tap to center" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="Tap and hold to reset" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="Touch and move to drag" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="Pinch (touch with two fingers) to scale and rotate" Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/>
<TextBlock Text="Flick (drag and release the touch while still moving) will show flick data on bottom of screen." Style="{StaticResource PhoneTextNormalStyle}" TextWrapping="Wrap"/>
</StackPanel>
<TextBlock x:Name="flickData" Text="Flick:" Style="{StaticResource PhoneTextNormalStyle}" VerticalAlignment="Bottom"/>
<Image x:Name="image" Source="/map.jpg" RenderTransformOrigin="0.5,0.5" CacheMode="BitmapCache">
<Image.RenderTransform>
<CompositeTransform x:Name="transform"/>
</Image.RenderTransform>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener
Tap="OnTap" Hold="OnHold"
DragStarted="OnDragStarted" DragDelta="OnDragDelta" DragCompleted="OnDragCompleted"
Flick="OnFlick"
PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" PinchCompleted="OnPinchCompleted"/>
</toolkit:GestureService.GestureListener>
</Image>
</Grid>
And the cs source:
public partial class GestureSample : PhoneApplicationPage
{
double initialAngle;
double initialScale;
public GestureSample()
{
InitializeComponent();
}
private void OnTap(object sender, GestureEventArgs e)
{
transform.TranslateX = transform.TranslateY = 0;
}
private void OnDoubleTap(object sender, GestureEventArgs e)
{
transform.ScaleX = transform.ScaleY = 1;
}
private void OnHold(object sender, GestureEventArgs e)
{
transform.TranslateX = transform.TranslateY = 0;
transform.ScaleX = transform.ScaleY = 1;
transform.Rotation = 0;
}
private void OnDragStarted(object sender, DragStartedGestureEventArgs e)
{
image.Opacity = 0.3;
}
private void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
transform.TranslateX += e.HorizontalChange;
transform.TranslateY += e.VerticalChange;
}
private void OnDragCompleted(object sender, DragCompletedGestureEventArgs e)
{
image.Opacity = 1.0;
}
private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
{
Point point0 = e.GetPosition(image, 0);
Point point1 = e.GetPosition(image, 1);
Point midpoint = new Point((point0.X + point1.X) / 2, (point0.Y + point1.Y) / 2);
image.RenderTransformOrigin = new Point(midpoint.X / image.ActualWidth, midpoint.Y / image.ActualHeight);
initialAngle = transform.Rotation;
initialScale = transform.ScaleX;
image.Opacity = 0.8;
}
private void OnPinchDelta(object sender, PinchGestureEventArgs e)
{
transform.Rotation = initialAngle + e.TotalAngleDelta;
transform.ScaleX = transform.ScaleY = initialScale * e.DistanceRatio;
}
private void OnPinchCompleted(object sender, PinchGestureEventArgs e)
{
image.Opacity = 1.0;
}
private void OnFlick(object sender, FlickGestureEventArgs e)
{
flickData.Text = string.Format("{0} Flick: Angle {1} Velocity {2},{3}",
e.Direction, Math.Round(e.Angle), e.HorizontalVelocity, e.VerticalVelocity);
}
}
It works pretty well for small images (less then 2000x2000 pixels). But in my example, i have this huge metro map (http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.png or vector http://www.vasttrafik.se/upload/Linjekartor_hogupplost/Goteborg2010/Linjen%C3%A4tskarta-101212.pdf). It would be even nicer if the user could scale a vector image but even importing such a huge vector is a serious performance issue.
Maybe i could split the image up into several "multi-scale images" and use this http://dotnetbyexample.blogspot.com/2010/08/windows-phone-7-multi-touch-panzoom.html, but i don't really know how to use his class :(
Any ideas? How would you guys solve this problem?
Thanks
Richard
The ideal approach for your solution is to use MultiScaleImage
, which is specifically designed to display large image data. However, in order to work with MultiScaleImage
you need to get your iamge data prepared int he right format. Basically, you need the image sliced up and rescaled, etc so that the user loads as little information as possible while they zoom in and out of your image.
The DeepZoom documentation describes the process and has links to the DeepZoom Composer tool, which you use to prepare your image data.
Once you've got the MultiScaleImage
approach working, you can then look at using Laurent's Multitouch Behavior (if necessary) to provide additional user interactions.
Have you heard of Silverlight Deep-Zoom?
http://msdn.microsoft.com/en-us/library/cc645050(v=vs.95).aspx
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With