RadialGradientBrush on Rounded-Corner Rectangle

白昼怎懂夜的黑 提交于 2019-12-06 08:32:29

For a rounded rectangle you can do it all in XAML using radial gradients for the corners and linear gradients for the sides.

The example uses a ViewBox so the Size doesn't need to be set both on the grid and its clip path. If you need it to resize keeping the same border radius you could bind RectangleGeometry.Rect and use a ValueConverter. The gradient and the RadiusX and RadiusY properties can be easily changed in one place.

    <Viewbox Stretch="Fill">
        <Grid Width="100" Height="100">
            <Grid.Resources>
                <Color x:Key="inside">White</Color>
                <GradientStopCollection x:Key="gradient">
                    <GradientStop Color="Black" Offset="1"/>
                    <GradientStop Color="{DynamicResource inside}" Offset="0.2"/>
                </GradientStopCollection>
            </Grid.Resources>
            <Grid.Clip>
                <RectangleGeometry RadiusX="15" RadiusY="30" Rect="0,0,100,100" x:Name="clip" />
            </Grid.Clip>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="{Binding RadiusX, ElementName=clip}" />
                <ColumnDefinition Width="1*"/>
                <ColumnDefinition Width="{Binding RadiusX, ElementName=clip}" />
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="{Binding RadiusY, ElementName=clip}"/>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="{Binding RadiusY, ElementName=clip}"/>
            </Grid.RowDefinitions>
            <Rectangle Grid.Column="1" Margin="-1,0">
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="0,0" MappingMode="RelativeToBoundingBox" StartPoint="0,1" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="2" Grid.Row="1" Margin="0,-1">
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="1,0" MappingMode="RelativeToBoundingBox" StartPoint="0,0" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="1" Grid.Row="2" Margin="-1,0">
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Row="1" Margin="0,-1">
                <Rectangle.Fill>
                    <LinearGradientBrush EndPoint="0,0" MappingMode="RelativeToBoundingBox" StartPoint="1,0" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="1" Grid.Row="1" Margin="-1">
                <Rectangle.Fill>
                    <SolidColorBrush Color="{DynamicResource inside}" />
                </Rectangle.Fill>
                </Rectangle>
            <Rectangle>
                <Rectangle.Fill>
                    <RadialGradientBrush Center="1,1" RadiusX="1" RadiusY="1" GradientOrigin="1,1" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="2">
                <Rectangle.Fill>
                    <RadialGradientBrush Center="0,1" RadiusX="1" RadiusY="1" GradientOrigin="0,1" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Column="2" Grid.Row="2">
                <Rectangle.Fill>
                    <RadialGradientBrush Center="0,0" RadiusX="1" RadiusY="1" GradientOrigin="0,0" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
            <Rectangle Grid.Row="2">
                <Rectangle.Fill>
                    <RadialGradientBrush Center="1,0" RadiusX="1" RadiusY="1" GradientOrigin="1,0" GradientStops="{DynamicResource gradient}" />
                </Rectangle.Fill>
            </Rectangle>
        </Grid>
    </Viewbox>

If you need to a gradient to follow more complex shapes you can do it with a V3.0 PixelShader.

Here is a simple example composing a rounded-rectangle gradient out of more primitive gradients:

<Canvas>
    <Canvas.Resources>
        <GradientStopCollection x:Key="stops">
            <GradientStop Color="White" Offset="0"/>
            <GradientStop Color="Black" Offset="1"/>
        </GradientStopCollection>
        <RadialGradientBrush x:Key="cornerBrush" GradientStops="{StaticResource stops}"/>
        <LinearGradientBrush x:Key="topBrush" StartPoint="0,1" EndPoint="0,0" GradientStops="{StaticResource stops}"/>
        <LinearGradientBrush x:Key="leftBrush" StartPoint="1,0" EndPoint="0,0" GradientStops="{StaticResource stops}"/>
        <LinearGradientBrush x:Key="rightBrush" StartPoint="0,0" EndPoint="1,0" GradientStops="{StaticResource stops}"/>
        <LinearGradientBrush x:Key="bottomBrush" StartPoint="0,0" EndPoint="0,1" GradientStops="{StaticResource stops}"/>
    </Canvas.Resources>
    <Ellipse Canvas.Left="0" Canvas.Top="0"  Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
    <Ellipse Canvas.Left="200" Canvas.Top="0"  Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
    <Ellipse Canvas.Left="0" Canvas.Top="200"  Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
    <Ellipse Canvas.Left="200" Canvas.Top="200"  Width="100" Height="100" Fill="{StaticResource cornerBrush}"/>
    <Rectangle Canvas.Left="50" Canvas.Top="0" Width="200" Height="50" Fill="{StaticResource topBrush}"/>
    <Rectangle Canvas.Left="0" Canvas.Top="50" Width="50" Height="200" Fill="{StaticResource leftBrush}"/>
    <Rectangle Canvas.Left="250" Canvas.Top="50" Width="50" Height="200" Fill="{StaticResource rightBrush}"/>
    <Rectangle Canvas.Left="50" Canvas.Top="250" Width="200" Height="50" Fill="{StaticResource bottomBrush}"/>
    <Rectangle Canvas.Left="50" Canvas.Top="50" Width="200" Height="200" Fill="White"/>
</Canvas>

which produces this effect:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!