具有路径的WPF剪辑矩形未获得所需的输出

时间:2019-03-13 06:51:11

标签: wpf xaml geometry clip

我正在为流体容器创建一个用户控件。参考这篇文章https://pptcrafter.wordpress.com/2014/05/14/animation-liquids-filling-bubbling-etc/。我在矩形上使用流体(水)和容器路径(在这里烧杯)。我想以仅显示在容器中的方式裁剪水矩形。我尝试使用路径几何进行剪切,也使用不透明蒙版。但是没有得到想要的输出。我想我缺少了一些东西。请帮我找到那个。
所需的输出 _________________________________________________________________________
不裁剪:
_________________________________________________________________________

使用路径剪辑:

_________________________________________________________________________

使用不透明蒙版:
_________________________________________________________________________


<UserControl
x:Class="FluidFill.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FluidFill"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300">
<UserControl.Resources>
    <PathFigureCollection
        x:Key="fig">M0,0 L10,10 V135 A10,10 0 0 0 20,145 H 130 A10,10 0 0 0 140,135 V5 L145,0 Z</PathFigureCollection>
</UserControl.Resources>
<Grid
    Background="White">

        <Path Panel.ZIndex="1" RenderTransformOrigin="0.5,0.5"
            x:Name="ActualContainer"
            Stroke="Black"
            Fill="Transparent"
            StrokeThickness="2"
            Data="M0,0 L10,10 V135 A10,10 0 0 0 20,145 H 130 A10,10 0 0 0 140,135 V5 L145,0 Z"
            >
            <!--<Path.Effect>
                <DropShadowEffect
                    Color="#FF3C494B"
                    ShadowDepth="3"
                    Opacity="0.6" />
            </Path.Effect>-->
            <Path.RenderTransform>
            <TransformGroup>
                <TranslateTransform
                    X="50"
                    Y="30" />
                <RotateTransform
                    Angle="20" />
            </TransformGroup>
        </Path.RenderTransform>
        </Path>

    <Rectangle x:Name="Wtr"
        Height="200"
        Width="375"
        Fill="#4F81BD" Margin="0,52.5,0,47.5">
        <!--<Rectangle.Clip>
            <PathGeometry Transform="{Binding ElementName=ActualContainer,Path=RenderTransform}" Figures="{StaticResource fig}">                  
            </PathGeometry>
        </Rectangle.Clip>-->
        <!--<Rectangle.OpacityMask>
            <VisualBrush
                TileMode="Tile"
                Stretch="None">
                <VisualBrush.Visual>
                    <Grid
                        x:Name="waveGrid">

                        <Path  RenderTransform="{Binding ElementName=ActualContainer,Path=RenderTransform}"
                            Fill="#FF82C6FF"
                            Data="M0,0 L10,10 V135 A10,10 0 0 0 20,145 H 130 A10,10 0 0 0 140,135 V5 L145,0 Z"
                            />                            
                    </Grid>
                </VisualBrush.Visual>

            </VisualBrush>

        </Rectangle.OpacityMask>-->
    </Rectangle>


</Grid>

2 个答案:

答案 0 :(得分:1)

最好设置路径的几何图形的RenderTransform属性,而不是设置路径的Transform

现在,您可以通过第二条路径的RectangleGeometry中Rect的Y值轻松调整水位高度。

<Grid Background="White">
    <Path x:Name="ActualContainer" Panel.ZIndex="1" Stroke="Black" StrokeThickness="2">
        <Path.Data>
            <PathGeometry Figures="M0,0 L10,10 V135 A10,10 0 0 0 20,145 H 130 A10,10 0 0 0 140,135 V5 L145,0 Z">
                <PathGeometry.Transform>
                    <TransformGroup>
                        <TranslateTransform X="50" Y="30"/>
                        <RotateTransform Angle="20"/>
                    </TransformGroup>
                </PathGeometry.Transform>
            </PathGeometry>
        </Path.Data>
    </Path>

    <Path Data="{Binding Data, ElementName=ActualContainer}" Fill="#4F81BD">
        <Path.Clip>
            <RectangleGeometry Rect="0,125,200,200"/>
        </Path.Clip>
    </Path>
</Grid>

答案 1 :(得分:1)

使用CombinedGeometry可以轻松抽取水。这样,您可以选择绘制两个Geometry重叠/相交的区域。现在,您可以绘制一个巨大的Rectangle,如水位+烧杯,然后生成的Area是您想要的输出。

XAML:

<UserControl.Resources>
    <!-- Form of the Beaker with Rotation -->
    <PathGeometry x:Key="BeakerForm" Figures="M0,0 L10,10 V135 A10,10 0 0 0 20,145 H 130 A10,10 0 0 0 140,135 V5 L145,0 Z">
        <PathGeometry.Transform>
            <!-- Angle of the Beaker Rotation (Note: CenterX must be the highest X-Coordinate of the Figures-Data) -->
            <RotateTransform Angle="10" CenterX="145"/>
        </PathGeometry.Transform>
    </PathGeometry>
</UserControl.Resources>

<!-- Canvas to draw the Beaker -->
<Canvas Background="White" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="100,100">
    <!-- Beaker Fill-Water -->
    <Path Fill="#4F81BD" RenderTransformOrigin="1,0">
        <Path.Data>
            <!-- A Rectangle and a Beaker wil be drawn and the blue areais only 
                 visible where theese two figures intersect (overlap) -->
            <CombinedGeometry GeometryCombineMode="Intersect">
                <CombinedGeometry.Geometry1>
                    <StaticResource ResourceKey="BeakerForm"/>
                </CombinedGeometry.Geometry1>
                <CombinedGeometry.Geometry2>
                    <RectangleGeometry Rect="-65,0 315,150" />
                </CombinedGeometry.Geometry2>
            </CombinedGeometry>
        </Path.Data>
    </Path>

    <!-- Beaker line in the foreground -->
    <Path RenderTransformOrigin="1,0" Stroke="Black" Fill="Transparent" StrokeThickness="2" Data="{StaticResource BeakerForm}"/>
</Canvas>

这样,您可以调整Angle中的BeakerForm,水位将适应它。

enter image description here

修改

烧杯的大小为x = 150和y = 150(四舍五入)。当旋转45°时,它达到最大宽度,即sqrt(150 ^ 2 + 150 ^ 2)=〜215的宽度。高度不受影响,因为我们将水位设置为0。因此,我们需要一个矩形,其覆盖区域(红色)从(150-215)= -65到150(315)和从0到150(高度),如下所示:

enter image description here

然后我们可以使用theese数字获得Rect="-65,0 315,150"

注意:“旋转中心”位于“烧杯/正方形”的右上角,旋转角度为ClockWise(cw)。