Scale WPF canvas relative to center, not top left
I am writing a program to create shortcuts. In this program I have a canvas with a white rectangle in the center, with several objects that the user can resize, drag and drop, etc. Over it. I also have the option to zoom in on the canvas, which I do using ScaleTransform
via LayoutTransform
. I want to have it so that when the user zooms in, the canvas zooms in at the center and not in relation to the top right.
Here's a demo:
The canvas is currently scaled like this:
I need it to be like this:
How can I accomplish this task without rearranging the elements in the canvas as it zooms in?
Note . I am using LayoutTransform since I have to insert this into ScrollViewer
. RenderTransform
does this, but prevents the user from scrolling when canvas elements exceed the visible boundaries of the canvas.
source to share
You should be able to accomplish the same as RenderTransformOrigin using a transform that combines the two translations around scaling. For example. using TransformGroup or combining matrices for MatrixTransform.
Specifically: translate the center point (X, Y) to (0,0) using the shift offsets -X and -Y, do a scale transformation, and then translate (0,0) back to the origin (X, Y) using X and Y shear displacement.
It's hard for me to know for sure without having a specific code example, but I have a vague feeling that a RenderTransform should be used, possibly applied differently than you would prefer (for example, adding a new container to the hierarchy and applying to it). But assuming the RenderTransform just doesn't work, the above should be.
source to share
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="600" Width="600">
<Grid>
<ScrollViewer>
<Border>
<Border.LayoutTransform>
<TransformGroup>
<ScaleTransform ScaleX="2.0" ScaleY="2.0"/>
</TransformGroup>
</Border.LayoutTransform>
<Canvas Background="Red" Width="500" Height="500" VerticalAlignment="Center" HorizontalAlignment="Center">
<Canvas.RenderTransform>
<TransformGroup>
<TranslateTransform X="0" Y="-100"/>
</TransformGroup>
</Canvas.RenderTransform>
<Rectangle Canvas.Left="200" Canvas.Top="200" Width="100" Height="100" Fill="Yellow"/>
</Canvas>
</Border>
</ScrollViewer>
</Grid>
</Window>
source to share