SourceChord

C#とXAML好きなプログラマの備忘録。最近はWPF系の話題が中心です。

Blendを使ってButtonのホバーエフェクトを作る Part5

Webサイトのナビゲーション風ボタンです。
ButtonのコンテンツにDropShadowEffectをかけて、ぼわっと光ってるように表示します。
こういう動作は、ButtonよりHyperLinkとして作った方が適切な気もするけど、
WPFのHyperLinkコントロール、使い勝手悪いし。。。

以下のようなボタンを作ります。

動作内容

フォーカス時には、ぼかし部分がうっすらと明滅するようにしています。
また、ホバー時には文字を少し大きく、クリック時にはぼかし半径を縮めて少し下に移動します。

使い方

こんな風に、ButtonのBackgroundプロパティの色を、ぼかし部分の色として使用しています。
あと、フォーカスが当たったときに、デフォルトの点線の枠が出るとかっこ悪いので、FocusVisualStyleをNullに指定しています。

        <Button Content="Link1"
                Foreground="Black"
                Background="Orange"
                TextBlock.FontSize="20"
                Template="{DynamicResource ButtonControlTemplate10}"
                FocusVisualStyle="{x:Null}" />

コントロールテンプレートはこんな感じ

        <ControlTemplate x:Key="ButtonControlTemplate10" TargetType="{x:Type Button}">
            <Grid>
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualState x:Name="Normal">
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1.0">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1.0">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1.1">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1.1">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Pressed">
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="1.1">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="1.1">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.BlurRadius)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="5">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="0">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                    <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="2">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <CubicEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Disabled"/>
                    </VisualStateGroup>
                    <VisualStateGroup x:Name="FocusStates">
                        <VisualState x:Name="Unfocused"/>
                        <VisualState x:Name="Focused">
                            <Storyboard AutoReverse="True" RepeatBehavior="Forever">
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.Opacity)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="1">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <SineEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0.6">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <SineEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Effect).(DropShadowEffect.BlurRadius)" Storyboard.TargetName="contentPresenter">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="10">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <SineEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                    <EasingDoubleKeyFrame KeyTime="0:0:1" Value="10">
                                        <EasingDoubleKeyFrame.EasingFunction>
                                            <SineEase EasingMode="EaseInOut"/>
                                        </EasingDoubleKeyFrame.EasingFunction>
                                    </EasingDoubleKeyFrame>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <ContentPresenter x:Name="contentPresenter" HorizontalAlignment="Center" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" >
                    <ContentPresenter.Effect>
                        <DropShadowEffect BlurRadius="5" Opacity="0.5" ShadowDepth="0" Color="{Binding Background.Color, RelativeSource={RelativeSource TemplatedParent}}" />
                    </ContentPresenter.Effect>
                    <ContentPresenter.RenderTransform>
                        <TransformGroup>
                            <ScaleTransform/>
                            <SkewTransform/>
                            <RotateTransform/>
                            <TranslateTransform/>
                        </TransformGroup>
                    </ContentPresenter.RenderTransform>
                </ContentPresenter>
            </Grid>
        </ControlTemplate>