Как нарисовать падающую тень на прозрачном прямоугольнике? - PullRequest
4 голосов
/ 19 февраля 2010

Когда я добавляю эффект растрового изображения в прямоугольник, он учитывает прозрачность прямоугольника (имеет смысл).Есть ли способ отрисовки тени на прозрачном прямоугольнике, как если бы прямоугольник был непрозрачным?то есть то, что могло бы появиться, представляет собой «дыру» в форме прямоугольника с тенями.

Вот XAML для прозрачного прямоугольника с тенями - ничего не отображается:

<Rectangle Fill="Transparent" Margin="10" Width="100" Height="100">
  <Rectangle.BitmapEffect>
    <DropShadowBitmapEffect/>
  </Rectangle.BitmapEffect>
</Rectangle>

Ответы [ 4 ]

5 голосов
/ 20 февраля 2010

Оставь это в Кахамле. Он создает прозрачный прямоугольник размером 500x500 с декоратором SystemDropShadowChrome. Клип падающей тени настроен на исключение области прямоугольника.

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:theme="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Canvas>
        <theme:SystemDropShadowChrome Margin="0,0,5,5">
            <Rectangle Width="500" Height="500" Fill="transparent"/>
            <theme:SystemDropShadowChrome.Clip>
                <CombinedGeometry GeometryCombineMode="Exclude">
                    <CombinedGeometry.Geometry1>
                        <RectangleGeometry Rect="0,0,505,505"/>
                    </CombinedGeometry.Geometry1>
                    <CombinedGeometry.Geometry2>
                        <RectangleGeometry Rect="0,0,500,500"/>
                    </CombinedGeometry.Geometry2>
                </CombinedGeometry>
            </theme:SystemDropShadowChrome.Clip>
        </theme:SystemDropShadowChrome>
    </Canvas>
</Page>

Если вы хотите, чтобы ваша тень имела закругленные углы, тогда установите CornerRadius из SystemDropShadowChrome на любое (скажем, 10), тогда значения Geometry1 Left и Top равны 10 затем RadiusX и RadiusY каждого RectangleGeometry до 10.

1 голос
/ 19 февраля 2010

Хорошо, вот один из долгих способов реализации прямоугольной «тени» без использования растрового эффекта. В этом случае центр теневого прямоугольника окрашен, но его можно установить прозрачным, чтобы получить тень в стиле «гало» (т. Е. Равную по всей окружности - не смещенную)

<UserControl x:Class="RectShadow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:System="clr-namespace:System;assembly=mscorlib">
    <UserControl.Resources>
        <System:Double x:Key="CornerSize">5</System:Double>
        <Color x:Key="ShadowColor">#60000000</Color>
        <Color x:Key="TransparentColor">#00000000</Color>
    </UserControl.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto"/>
            <RowDefinition/>
            <RowDefinition Height="auto"/>
        </Grid.RowDefinitions>   
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition/>
            <ColumnDefinition Width="auto"/>
        </Grid.ColumnDefinitions>

        <Rectangle Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
            <Rectangle.Fill>
                <RadialGradientBrush Center="1,1" GradientOrigin="1,1" RadiusX="1" RadiusY="1">
                    <GradientStop Color="{StaticResource ShadowColor}"/>
                    <GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
                </RadialGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Row="2" Grid.Column="2" Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
            <Rectangle.Fill>
                <RadialGradientBrush Center="0,0" GradientOrigin="0,0" RadiusX="1" RadiusY="1">
                    <GradientStop Color="{StaticResource ShadowColor}"/>
                    <GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
                </RadialGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Row="0" Grid.Column="2" Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
            <Rectangle.Fill>
                <RadialGradientBrush Center="0,1" GradientOrigin="0,1" RadiusX="1" RadiusY="1">
                    <GradientStop Color="{StaticResource ShadowColor}"/>
                    <GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
                </RadialGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Row="2" Grid.Column="0" Width="{StaticResource CornerSize}" Height="{StaticResource CornerSize}">
            <Rectangle.Fill>
                <RadialGradientBrush Center="1,0" GradientOrigin="1,0" RadiusX="1" RadiusY="1">
                    <GradientStop Color="{StaticResource ShadowColor}"/>
                    <GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
                </RadialGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Column="1">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0,1">
                    <GradientStop Offset="1" Color="{StaticResource ShadowColor}"/>
                    <GradientStop Color="{StaticResource TransparentColor}"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>


        <Rectangle Grid.Column="1" Grid.Row="2">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="0,1">
                    <GradientStop Color="{StaticResource ShadowColor}"/>
                    <GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Row="1">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="1,0">
                    <GradientStop Offset="1" Color="{StaticResource ShadowColor}"/>
                    <GradientStop Color="{StaticResource TransparentColor}"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Row="1" Grid.Column="2">
            <Rectangle.Fill>
                <LinearGradientBrush EndPoint="1,0">
                    <GradientStop Color="{StaticResource ShadowColor}"/>
                    <GradientStop Offset="1" Color="{StaticResource TransparentColor}"/>
                </LinearGradientBrush>
            </Rectangle.Fill>
        </Rectangle>

        <Rectangle Grid.Row="1" Grid.Column="1">
            <Rectangle.Fill>
                <SolidColorBrush Color="{StaticResource ShadowColor}"/>
            </Rectangle.Fill>
        </Rectangle>
    </Grid>
</UserControl>
1 голос
/ 19 февраля 2010

Я бы хотел увидеть лучшее решение, но вот что я обычно делаю ( остерегайтесь : жуткий код впереди).

Оберните прямоугольник в три-четыре прямоугольника и поиграйте сцвет обводки, делая его темнее и темнее по мере приближения к исходному прямоугольнику.Вот код:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
   <Grid>
      <Rectangle
         Width="106"
         Height="106"
         Stroke="#10000000"
         StrokeThickness="1"/>
      <Rectangle
         Width="104"
         Height="104"
         Stroke="#5C000000"
         StrokeThickness="1"/>
      <Rectangle
         Width="102"
         Height="102"
         Stroke="#AC000000"
         StrokeThickness="1"/>
      <Rectangle
         Width="100"
         Height="100"
         Fill="Transparent"
         Stroke="#FF000000"
         StrokeThickness="1">
      </Rectangle>
   </Grid>
</Page>

Это дает вам:

альтернативный текст http://img521.imageshack.us/img521/7664/shadowo.jpg

Другой подход будет с границами - лучше, потому что у вас нетчтобы указать размеры, когда вы помещаете их в Grid.

И лучший подход (хотя и не реализованный): пользовательский пиксельный шейдер, который делает то, что вы хотите.

0 голосов
/ 13 октября 2011

обернуть прямоугольник в рамку. и добавить тень к границе. вы получите тот же эффект.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...