问题描述
在一个Canvas中绘制了多个Polygon,由于坐标可能超出界面显示范围,需要将绘制的Polygon居中显示,并且缩放至界面大小,效果如下:
xaml代码
<Border
x:Name="border"
Background="#fff"
ClipToBounds="True">
<Canvas
x:Name="canvas"
Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=Border}}"
Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource AncestorType=Border}}">
<Canvas.RenderTransform>
<TransformGroup />
</Canvas.RenderTransform>
</Canvas>
</Border>
实现代码
private void CenterAndScalePolygons()
{
if (canvas == null || canvas.Children.Count == 0)
{
return;
}
// 获取所有 Polygon 的边界框
Rect boundingBox = GetBoundingBox(canvas.Children.OfType<Polygon>());
// 计算需要进行的缩放和平移操作
double scaleX = border.ActualWidth / boundingBox.Width;
double scaleY = border.ActualHeight / boundingBox.Height;
// 使用较小的缩放比例,保持图形完全在 Canvas 内显示
double scale = Math.Min(scaleX, scaleY);
double offsetX = border.ActualWidth / 2 - (boundingBox.Left + boundingBox.Right) / 2 * scale;
double offsetY = border.ActualHeight / 2 - (boundingBox.Top + boundingBox.Bottom) / 2 * scale;
// 遍历 Polygon 进行缩放和平移
foreach (var polygon in canvas.Children.OfType<Polygon>())
{
ScaleTransform scaleTransform = new ScaleTransform(scale, scale);
TranslateTransform translateTransform = new TranslateTransform(offsetX, offsetY);
TransformGroup transformGroup = new TransformGroup();
transformGroup.Children.Add(scaleTransform);
transformGroup.Children.Add(translateTransform);
polygon.RenderTransform = transformGroup;
// 调整 Polygon 边框线宽
polygon.StrokeThickness = 1 / scale;
}
}
private Rect GetBoundingBox(IEnumerable<Polygon> polygons)
{
double minX = double.MaxValue;
double minY = double.MaxValue;
double maxX = double.MinValue;
double maxY = double.MinValue;
foreach (Polygon polygon in polygons)
{
foreach (Point point in polygon.Points)
{
minX = Math.Min(minX, point.X);
minY = Math.Min(minY, point.Y);
maxX = Math.Max(maxX, point.X);
maxY = Math.Max(maxY, point.Y);
}
}
return new Rect(minX, minY, maxX - minX, maxY - minY);
}