【WPF】ウェットフロア効果をかける

By | 2011年8月31日

GUIの表示が地面に写り込んだようなデザインを最近良く見かける。このような効果をウェットフロアというそうだ。
今回は、以下のようなウェットフロア効果がかかったGUIをxamlで実装していくことを考える。

まずは、効果が何もかかっていない状態のxamlを示す。

MainWindow.xaml

<Window x:Class="WpfWetFloorLesson.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <!-- 適当なGUI -->
        <Border BorderThickness="8" BorderBrush="AliceBlue" Background="AliceBlue" Name="inputArea" Height="72">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition Height="4"></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label Background="Azure">Name</Label>
                <Label Background="Beige" Grid.Row="2">Address</Label>
                <TextBox Grid.Column="1"></TextBox>
                <TextBox Grid.Row="2" Grid.Column="1"></TextBox>
            </Grid>
        </Border>
    </StackPanel>
</Window>

このxamlを実行すると以下のように表示される。

このGUIに対してウェットフロア効果をかけていく。
まずは、GUIの真下に、上のイメージと全く同じものが表示されるようにVisualBrushを適用したRectangleを配置する。
そのxamlは以下のようになる。

<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
    <Rectangle.Fill>
        <VisualBrush Visual="{Binding ElementName=inputArea}" />
    </Rectangle.Fill>
</Rectangle>

そして、ここまでの実行結果は以下のようになる。

次に、写り込み効果として追加したRectangleを180度回転させる。

<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
    <Rectangle.Fill>
        <VisualBrush Visual="{Binding ElementName=inputArea}" />
    </Rectangle.Fill>
    <Rectangle.RenderTransform>
        <TransformGroup>
            <!-- 180度回転させる -->
            <ScaleTransform ScaleY="-1" />
        </TransformGroup>
    </Rectangle.RenderTransform>
</Rectangle>


このままだと、元のGUIに重なってしまうので、Rectangleを自分の高さの分だけ下に移動する必要がある。

<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
    <Rectangle.Fill>
        <VisualBrush Visual="{Binding ElementName=inputArea}" />
    </Rectangle.Fill>
    <Rectangle.RenderTransform>
        <TransformGroup>
            <!-- 180度回転させる -->
            <ScaleTransform ScaleY="-1" />
            <!-- 自分の高さの分だけ下に移動する -->
            <TranslateTransform Y="{Binding ElementName=inputArea,Path=Height}" />
        </TransformGroup>
    </Rectangle.RenderTransform>
</Rectangle>


最後に、仕上げとしてぼかしを入れる。

<Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
    <Rectangle.Fill>
        <VisualBrush Visual="{Binding ElementName=inputArea}" />
    </Rectangle.Fill>
    <!-- ぼかしを入れる -->
    <Rectangle.OpacityMask>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="#AA000000" Offset="1" />
            <GradientStop Color="#00000000" Offset="0" />
        </LinearGradientBrush>
    </Rectangle.OpacityMask>
    <Rectangle.RenderTransform>
        <TransformGroup>
            <!-- 180度回転させる -->
            <ScaleTransform ScaleY="-1" />
            <!-- 自分の高さの分だけ下に移動する -->
            <TranslateTransform Y="{Binding ElementName=inputArea,Path=Height}" />
        </TransformGroup>
    </Rectangle.RenderTransform>
</Rectangle>


こうして、ウェットフロア効果を掛けることが出来た。
最後に、これまでのxaml全体を示す。

MainWindow.xaml

<Window x:Class="WpfWetFloorLesson.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel>
        <!-- 適当なGUI -->
        <Border BorderThickness="8" BorderBrush="AliceBlue" Background="AliceBlue" Name="inputArea" Height="72">
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition></RowDefinition>
                    <RowDefinition Height="4"></RowDefinition>
                    <RowDefinition></RowDefinition>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="50"></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <Label Background="Azure">Name</Label>
                <Label Background="Beige" Grid.Row="2">Address</Label>
                <TextBox Grid.Column="1"></TextBox>
                <TextBox Grid.Row="2" Grid.Column="1"></TextBox>
            </Grid>
        </Border>
        <!-- ウェットフロア効果 -->
        <Rectangle Height="{Binding ElementName=inputArea,Path=Height}">
            <Rectangle.Fill>
                <VisualBrush Visual="{Binding ElementName=inputArea}" />
            </Rectangle.Fill>
            <!-- ぼかしを入れる -->
            <Rectangle.OpacityMask>
                <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
                    <GradientStop Color="#AA000000" Offset="1" />
                    <GradientStop Color="#00000000" Offset="0" />
                </LinearGradientBrush>
            </Rectangle.OpacityMask>
            <Rectangle.RenderTransform>
                <TransformGroup>
                    <!-- 180度回転させる -->
                    <ScaleTransform ScaleY="-1" />
                    <!-- 自分の高さの分だけ下に移動する -->
                    <TranslateTransform Y="{Binding ElementName=inputArea,Path=Height}" />
                </TransformGroup>
            </Rectangle.RenderTransform>
        </Rectangle>
    </StackPanel>
</Window>

このように、WPFではxamlを書いていくだけでリッチな効果を得ることができる。
WPFの表現力の可能性を感じさせる一例である。

参考サイト:
http://msdn.microsoft.com/ja-jp/magazine/cc163455.aspx


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です