WPF 基础 - 绘画 2) Path
阅读原文时间:2023年07月13日阅读:1

1. Path 霸中霸

既可以替代其他几种图形,也可以将直线、圆弧、贝尔赛曲线组合起来;

重要属性:Geometry Data;

其中 Geometry 为抽象类,不可实例化,可使用其子类:

LineGeometry、RectangleGeometry、EllipseGeometry、PathGeometry、

StreamGeometry、CombinedGeometry、GeometryGroup

<StackPanel Margin="20 5">
    <StackPanel.Resources>
        <LinearGradientBrush x:Key="DefaultColor">
            <GradientStop Color="#ff4b1f" Offset="0.1"/>
            <GradientStop Color="#1fddff" Offset="1"/>
        </LinearGradientBrush>
    </StackPanel.Resources>
        <StackPanel Margin="4 0">
        <Line Stroke="{StaticResource DefaultColor}" StrokeThickness="1" Margin="0 5"
              X1="0" Y1="0" X2="20" Y2="20" />
        <Path Stroke="{StaticResource DefaultColor}" StrokeThickness="1">
            <Path.Data>
                <LineGeometry StartPoint="0,0" EndPoint="20,20"/>
            </Path.Data>
        </Path>
    </StackPanel>

    <StackPanel Margin="4 0">
        <Rectangle Stroke="{StaticResource DefaultColor}" StrokeThickness="1" VerticalAlignment="Top" Margin="0 5"
                   Width="20" Height="20"/>
        <Path Stroke="{StaticResource DefaultColor}" StrokeThickness="1">
            <Path.Data>
                <RectangleGeometry Rect="0.5,0.5 19,19"/>
            </Path.Data>
        </Path>
    </StackPanel>

    <StackPanel Margin="4 0">
        <Ellipse StrokeThickness="1" Stroke="{StaticResource DefaultColor}" VerticalAlignment="Top" Margin="0 5"
                 Width="20" Height="20" />
        <Path Stroke="{StaticResource DefaultColor}" StrokeThickness="1">
            <Path.Data>
                <EllipseGeometry RadiusX="10" RadiusY="10" Center="10,10"/>
            </Path.Data>
        </Path>
    </StackPanel>

    <Path Stroke="{StaticResource DefaultColor}" StrokeThickness="1">
        <Path.Data>
            <PathGeometry>
                <PathFigure StartPoint="0,5" IsClosed="True" >
                    <LineSegment Point="15,10"></LineSegment>
                    <ArcSegment Point="30,20" Size="20,30" SweepDirection="Counterclockwise"></ArcSegment>
                    <BezierSegment Point1="30,45" Point2="50,30" Point3="40,50"></BezierSegment>
                </PathFigure>
            </PathGeometry>
        </Path.Data>
    </Path>
</StackPanel>

效果:

PathGeometry 的 Figures 属性可以容纳 PathFigure 对象,PathFigure 的 Segments 属性又可以容纳各种线段用于结合成复杂图形;

默认内容属性可以简化标签写法。

1.1 线段类型

  • LineSegment 直线段
  • ArgSegment 圆弧
  • BezierSegment 贝塞尔曲线段
  • QuadraticBezierSegment 二次方贝塞尔曲线段
  • PolyLineSegment 多直线段
  • PolyBezierSegment 多贝塞尔曲线段
  • PolyQuadraticBezierSegment 多二次方贝塞尔曲线段

这些线段都以上一个线段的终点作为自己的起点,而第一个线段你的起点就是 PathFigure 的 StartPoint。

LineSegment : Point 表示终点
ArcSegment : Size 属性是完成椭圆的横、纵轴半径,
             SweepDirection 表明圆弧是顺/逆时针,Clockwise/Counterclockwise
             IsLargeArc 属性用于指明是否使用大弧去连接,
             RotationAngle 圆弧母椭圆的旋转角度
BezierSegment : Point1 表示起点先沿 Point1 点的方向走
                Point2 表示再沿 Point2 点的方向走
                Point3 最后到达 Point3 点(的平滑曲线)
QuadraticBezierSegment : 比 BezierSegment 少一个控制点

1.2 GeometryGroup

GeometryGroup 可以把多个 PathGeometry 的形状叠在一起。

1.3 路径标记语法

一条线段是一条标签,路径标记语法避免一个图形包括数十条线段导致数十行代码。

"M" 表示起点
<LineSegment Point="150, 50"/> = "L 150,50"
"H 180" 表示一条水平线段,横坐标到 180
"V 180" 表示垂直
"A 180,80 45 1 1 150,150" 圆弧 Size、
                               RotationAngle、
                               IsLargeArc(1=True)、
                               SweepDirection(1=Clockwise)、
                               Point
"C 250,0 50,200 300,200" 三次方贝塞尔BezierSegment Point1、Point2、Point3
"Q 150,-100 300,200" 二次方贝塞尔QuadraticBezierSegment Point1、Point2、Point3
"S 100,200 200,300" 平滑三次贝塞尔
"T 200,300" 平滑二次贝塞尔
"Z" 表示闭合

S、T 比较特殊,S 以前一条贝塞尔曲线的最后一个控制点以起点为对称中心的对称点作为自己的第一控制点,细品。平滑。

两者等价
<Path Data="M 0,0 C 6,0 18,30 30,30 S 51,0 60,0" Stroke="{StaticResource DefaultColor}" Margin="10 0"/>
<Path Data="M 0,0 C 6,0 18,30 30,30 C 42,30 51,0 60,0" Stroke="{StaticResource DefaultColor}"/>

效果:

1.4 Clip 窗口剪影

<Window x:Class="WpfAppTemplate.BrushWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:coll="clr-namespace:System.Collections;assembly=mscorlib"
        mc:Ignorable="d"
        Title="BrushWindow" Height="700" Width="700">
    <StackPanel>
        <Path x:Name="PP" Visibility="Collapsed" Data="M 10,10 A 130,130 0 1 1 100,500 Z"/>
        <Button Content="Clip the Window" Width="90" Height="40" Click="Button_Click_1"/>
    </StackPanel>
</Window>

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    this.Clip = this.PP.Data;
}

=>