Microsoft

In the previous article about UWP Inking platform as input for advanced scenarios, we have been able to

We are about to see how we can easily integrate a zoom functionality in our inking application.

 

 

The ScrollViewer control does 'almost' all the magic

You can start from the code explained in the previous blog post or from a blank UWP application.

We use the InkCanvas, but this time, we incorporate it inside a ScrollViewer:

<ScrollViewer x:Name="rootScrollViewer" 
ZoomMode="Enabled" MaxZoomFactor="5" MinZoomFactor="0.5"
HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto"
VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">

	<InkCanvas x:Name="inkCanvas" />

</ScrollViewer>

The important properties there are:

  • ZoomMode="Enabled" in order to be able to zoom (That means also that we can block the zoom at some point of time in the app if needed)
  • MinZoomFactor and MaxZoomFactor to control the minimum and maximum zoom level we want
  • HorizontalScrollMode and VerticalScrollMode for giving the ability to move inside the content

You can use the mouse wheel to make vary the zoom level, but the touch is much more friendly and the best interaction to use for tablets or Surface devices. The C# code provided for the sample of the previous article was also using touch for drawing; For this scenario, we have to allow only the mouse and the pen to dedicate the touch for the zoom gesture:

public MainPage()
{
    this.InitializeComponent();

    // Initialize the InkCanvas
    inkCanvas.InkPresenter.InputDeviceTypes =
        Windows.UI.Core.CoreInputDeviceTypes.Mouse |
        Windows.UI.Core.CoreInputDeviceTypes.Pen;
}
 

Zoom interaction with strokes on an UWP windowZoom interaction with strokes on an UWP window

 

Improving the zoom experience

Look at the following interactions about our sample. Do you notice the two limitations?

Zoom limitations in a UWP Window displaying a InkCanvasZoom limitations in a UWP Window displaying a InkCanvas

  1. The zoom is not focused on the area on which we do the zoom gesture (or not focused on the mouse cursor if we use the mouse wheel). The zoom always focus on the origin of the window
  2. We cannot move inside the zoomed content in doing right/left or top/bottom gestures

This not really usable for professional drawing or content creation apps, no? Let's use an extremely small magic joker: No code, no work! Just using a Viewbox control :party_popper: :

<Grid>
	<ScrollViewer x:Name="rootScrollViewer" 
	ZoomMode="Enabled" MaxZoomFactor="5" MinZoomFactor="0.5"
	HorizontalScrollMode="Auto" HorizontalScrollBarVisibility="Auto"
	VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto">


		<Viewbox x:Name="imageViewbox">
			<Grid>
				<Image x:Name="floorplanImage" 
				    Source="assets/SplashScreen.scale-200.png"/>
				<InkCanvas x:Name="inkCanvas" />
			</Grid>
		</Viewbox>

	</ScrollViewer>
</Grid>

With this code, you can zoom/unzoom focusing on a specific area and move freely inside the drawing:

Zoom full interactions in a UWP Window displaying a InkCanvasZoom full interactions in a UWP Window displaying a InkCanvas

 

This sample XAML code is the shortest possible for being able to read it with simplicity. Feel free to use some RowDefinition/ColumnDefinition with fixed Height/Width to really control the surface on which you allow the user to draw. Here, the Viewbox provides all the functionalities we need to adapt the content to the available space in the Grid.

 

 

Considerations for pen/touch/mouse inputs

You have seen in this sample that we do not accept touch for drawing on the InkCanvas. We use the pen or the mouse for inking. You understand that you will have to make a choice for input types. For example, you can consider the following options.

  • Allow only pen and mouse for drawing if you are using a device with a pen like Microsoft Surface; Then you dedicate the touch for zoom/move or other interactions.
  • Allow touch all the time for drawing if the device does not have a pen; You provide a button/switch in order to go to a "zoom/move" mode to be able to navigate inside the window's content.

Just remember that at any time, you can change the inputs allowed. Here is an example to enable or disable touch:

private void EnableTouchDrawing(bool enable)
{
    if (enable)
    {
        inkCanvas.InkPresenter.InputDeviceTypes = 
            CoreInputDeviceTypes.Mouse |
            CoreInputDeviceTypes.Touch |
            CoreInputDeviceTypes.Pen;
    }
    else
    {
        inkCanvas.InkPresenter.InputDeviceTypes = 
            CoreInputDeviceTypes.Mouse |
            CoreInputDeviceTypes.Pen;
    }
}

 

 

Wrapping up

Ink strokes or XAML Shapes that you are displaying on Canvas are vectorial shapes. Implementing functionalities to be able to move the 'sheet' on which you draw or zoom for a better visualization/precision is almost mandatory for inking applications. Define a strategy for handling and switching inputs is also key to provide the best user experience.

--

As always, the source code of the sample is on GitHub - https://github.com/microsoft/Windows-AppConsult-Samples-UWP/

 

@sbovo for the AppConsult team.

 

 

Inking series' articles

This article is part of a series exploring concepts about inking and XAML Shapes. Here are all links:

  1. Use the UWP Inking platform as input for advanced scenarios

  2. Handling zoom in Inking applications ⇐ You are here 

  3. Turning to the dark side of inking = UnprocessedInput 

  4. Free your mind: Start manipulating XAML Shapes

 

 

References