c# Canvas 缩放功能问题?使用矩阵变换放大到某个点后无法缩小到原始位置
c# Canvas Zoom Functionality issue ?Not able to zoom out to original postion after zooming in to a point using matrix transform
我正在尝试使用矩阵变换在 c# 中实现 canvas 缩放功能。我可以放大到一个特定的点,但是在缩小到原始比例(我限制为原始比例)时 canvas 的位置会发生变化(超出 window)。我希望它缩小到原来的位置。有人可以帮忙吗?
请找到下面的代码:
<ScrollViewer Name="C1_S" Grid.Row="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Bottom" Grid.ColumnSpan="2" >
<Canvas Name="canvas_core0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="600" Width="1000000" MouseWheel="Canvas_MouseWheel" ClipToBounds="True" >
<Canvas.Background>
<DrawingBrush TileMode="Tile" Viewport="0,20,40,40" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,50,50"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Gray" Thickness=".1"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
<Canvas.RenderTransform>
<MatrixTransform/>
</Canvas.RenderTransform>
</Canvas>
</ScrollViewer>
C# 代码:`
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var element = sender as UIElement;
var position = e.GetPosition(element);
if(e.Delta>0)
{
previousposition = position;
}
var transform = element.RenderTransform as MatrixTransform;
var matrix = transform.Matrix;
scrollcountprevious = scrollcountcurrent;
scrollcountcurrent = scrollcountcurrent + e.Delta;
// var scale1 = scrollcountcurrent > scrollcountprevious ? 1.1 : scrollcountcurrent <scrollcountprevious0 ? 1.0 : (1.0 / 1.1); // choose appropriate scaling factor
var scale1=1.0;
if (scrollcountcurrent > scrollcountprevious)
{
scale1 = 1.1;
matrix.ScaleAtPrepend(scale1, scale1, position.X, position.Y);
transform.Matrix = matrix;
}
else if (scrollcountcurrent < scrollcountprevious&&scrollcountcurrent>=0)
{
scale1 = 1 / 1.1;
matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y);
transform.Matrix = matrix;
}
else
{
scale1 = 1;
scrollcountcurrent = 0;
matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y);
transform.Matrix = matrix;
}
}
不确定我是否理解您想要实现的目标。此外,在 ScrollViewer 中使用 Canvas 可能会把事情搞砸。
但是这个 MouseWheel 处理程序可能会执行您想要的操作:
private double scale = 1;
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var element = (UIElement)sender;
var position = e.GetPosition(element);
var matrix = Matrix.Identity;
scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale / 1.1, 1.0);
matrix.ScaleAt(scale, scale, position.X, position.Y);
((MatrixTransform)element.RenderTransform).Matrix = matrix;
}
为了在 ScrollViewer 中也缩放 Canvas 的实际大小,请缩放其 LayoutTransform
而不是 RenderTransform
:
<Canvas.LayoutTransform>
<MatrixTransform/>
</Canvas.LayoutTransform>
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var element = (FrameworkElement)sender;
var position = e.GetPosition(element);
var matrix = Matrix.Identity;
scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale / 1.1, 1.0);
matrix.ScaleAt(scale, scale, position.X, position.Y);
((MatrixTransform)element.LayoutTransform).Matrix = matrix;
}
我正在尝试使用矩阵变换在 c# 中实现 canvas 缩放功能。我可以放大到一个特定的点,但是在缩小到原始比例(我限制为原始比例)时 canvas 的位置会发生变化(超出 window)。我希望它缩小到原来的位置。有人可以帮忙吗?
请找到下面的代码:
<ScrollViewer Name="C1_S" Grid.Row="0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" VerticalAlignment="Bottom" Grid.ColumnSpan="2" >
<Canvas Name="canvas_core0" Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Height="600" Width="1000000" MouseWheel="Canvas_MouseWheel" ClipToBounds="True" >
<Canvas.Background>
<DrawingBrush TileMode="Tile" Viewport="0,20,40,40" ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,50,50"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Gray" Thickness=".1"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
<Canvas.RenderTransform>
<MatrixTransform/>
</Canvas.RenderTransform>
</Canvas>
</ScrollViewer>
C# 代码:`
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var element = sender as UIElement;
var position = e.GetPosition(element);
if(e.Delta>0)
{
previousposition = position;
}
var transform = element.RenderTransform as MatrixTransform;
var matrix = transform.Matrix;
scrollcountprevious = scrollcountcurrent;
scrollcountcurrent = scrollcountcurrent + e.Delta;
// var scale1 = scrollcountcurrent > scrollcountprevious ? 1.1 : scrollcountcurrent <scrollcountprevious0 ? 1.0 : (1.0 / 1.1); // choose appropriate scaling factor
var scale1=1.0;
if (scrollcountcurrent > scrollcountprevious)
{
scale1 = 1.1;
matrix.ScaleAtPrepend(scale1, scale1, position.X, position.Y);
transform.Matrix = matrix;
}
else if (scrollcountcurrent < scrollcountprevious&&scrollcountcurrent>=0)
{
scale1 = 1 / 1.1;
matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y);
transform.Matrix = matrix;
}
else
{
scale1 = 1;
scrollcountcurrent = 0;
matrix.ScaleAtPrepend(scale1, scale1, previousposition.X, previousposition.Y);
transform.Matrix = matrix;
}
}
不确定我是否理解您想要实现的目标。此外,在 ScrollViewer 中使用 Canvas 可能会把事情搞砸。
但是这个 MouseWheel 处理程序可能会执行您想要的操作:
private double scale = 1;
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var element = (UIElement)sender;
var position = e.GetPosition(element);
var matrix = Matrix.Identity;
scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale / 1.1, 1.0);
matrix.ScaleAt(scale, scale, position.X, position.Y);
((MatrixTransform)element.RenderTransform).Matrix = matrix;
}
为了在 ScrollViewer 中也缩放 Canvas 的实际大小,请缩放其 LayoutTransform
而不是 RenderTransform
:
<Canvas.LayoutTransform>
<MatrixTransform/>
</Canvas.LayoutTransform>
private void Canvas_MouseWheel(object sender, MouseWheelEventArgs e)
{
var element = (FrameworkElement)sender;
var position = e.GetPosition(element);
var matrix = Matrix.Identity;
scale = Math.Max(e.Delta > 0 ? scale * 1.1 : scale / 1.1, 1.0);
matrix.ScaleAt(scale, scale, position.X, position.Y);
((MatrixTransform)element.LayoutTransform).Matrix = matrix;
}