WPF实现聚光灯效果

257 阅读1分钟

WPF开发者QQ群: 340500857  | 微信群 -> 进入公众号主页 加入组织

前言

        效果仿照 CSS聚光灯效果  

实现思路:

 

1. 设置底部Canvas背景色 #222222 。

2. 准备两个 TextBlock 控件在同一位置。

3. 设置底部 TextBlock 字体颜色Foreground="#323232"。

4. 设置上层 TextBlock  字体颜色为渐变色。

5. 设置上层 TextBlock.Clip 针对 EllipseGeometry 做 TranslateTransform 的X轴移动动画。

6. DoubleAnimation的To值为上层或者下层控件的ActualWidth获取此元素的呈现宽度。

7. 故事板初始化 Storyboard RepeatBehavior =RepeatBehavior.Forever,AutoReverse = true。`


 

效果预览(更多效果请下载源码体验)

![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2cd189b39211421385e690f97e5083c4~tplv-k3u1fbpfcp-zoom-1.image)

 一、SpotLight.cs 代码如下

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Media; using System.Windows.Media.Animation;

namespace WPFDevelopers.Controls { [TemplatePart(Name = TextBlockBottomTemplateName, Type = typeof(TextBlock))] [TemplatePart(Name = TextBlockTopTemplateName, Type = typeof(TextBlock))] [TemplatePart(Name = EllipseGeometryTemplateName, Type = typeof(EllipseGeometry))] public class SpotLight : Control { private const string TextBlockBottomTemplateName = "PART_TextBlockBottom"; private const string TextBlockTopTemplateName = "PART_TextBlockTop"; private const string EllipseGeometryTemplateName = "PART_EllipseGeometry"; private TextBlock _textBlockBottom, _textBlockTop; private EllipseGeometry _ellipseGeometry; public string Text { get { return (string)GetValue(TextProperty); } set { SetValue(TextProperty, value); } }

    public static readonly DependencyProperty TextProperty =
        DependencyProperty.Register("Text", typeof(string), typeof(SpotLight), new PropertyMetadata("WPFDevelopers"));
    static SpotLight()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SpotLight), new FrameworkPropertyMetadata(typeof(SpotLight)));
    }
    public SpotLight()
    {
        this.Loaded += SpotLight_Loaded;
    }

    private void SpotLight_Loaded(object sender, RoutedEventArgs e)
    {
        Canvas.SetLeft(_textBlockBottom, ActualWidth / 3);
        Canvas.SetTop(_textBlockBottom, ActualHeight / 3);
        Canvas.SetLeft(_textBlockTop, ActualWidth / 3);
        Canvas.SetTop(_textBlockTop, ActualHeight / 3);
    }

    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        _textBlockBottom = GetTemplateChild(TextBlockBottomTemplateName) as TextBlock;
        _textBlockTop = GetTemplateChild(TextBlockTopTemplateName) as TextBlock;
       
        _ellipseGeometry = GetTemplateChild(EllipseGeometryTemplateName) as EllipseGeometry;
        var center = new Point(FontSize/2, FontSize/2); 
        _ellipseGeometry.RadiusX = FontSize;
        _ellipseGeometry.RadiusY = FontSize;
        _ellipseGeometry.Center = center;
        if (_textBlockBottom != null && _textBlockTop != null && _ellipseGeometry != null)
            _textBlockTop.Loaded += _textBlockTop_Loaded;
    }


    private void _textBlockTop_Loaded(object sender, RoutedEventArgs e)
    {
        var doubleAnimation = new DoubleAnimation
        {
            To = _textBlockTop.ActualWidth,
            Duration = TimeSpan.FromSeconds(3)
        };
       
        Storyboard.SetTarget(doubleAnimation, _textBlockTop);
        Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(UIElement.Clip).(EllipseGeometry.Transform).(TranslateTransform.X)"));
        var storyboard = new Storyboard
        {
            RepeatBehavior = RepeatBehavior.Forever,
            AutoReverse = true
        };
        storyboard.Children.Add(doubleAnimation);
        storyboard.Completed += (s, q) => 
        {

        };
        storyboard.Begin();
    }
}

}


二、SpotLight.xaml 代码如下

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="Basic/ControlBasic.xaml"/>
</ResourceDictionary.MergedDictionaries>

<Style TargetType="{x:Type controls:SpotLight}" BasedOn="{StaticResource ControlBasicStyle}">
    <Setter Property="Background" Value="#222222"/>
    <Setter Property="FontSize" Value="60"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type controls:SpotLight}">
                <Canvas x:Name="PART_Canvas" Background="{TemplateBinding Background}">
                    <TextBlock x:Name="PART_TextBlockBottom" Text="{TemplateBinding Text}"
                               FontSize="{TemplateBinding FontSize}" FontFamily="Arial Black"
                               FontWeight="Bold" Foreground="#323232"/>
                    <TextBlock x:Name="PART_TextBlockTop" Text="{TemplateBinding Text}"
                               FontSize="{TemplateBinding FontSize}" FontFamily="Arial Black"
                               FontWeight="Bold">
                        <TextBlock.Foreground>
                            <LinearGradientBrush EndPoint="1,1" MappingMode="RelativeToBoundingBox" StartPoint="0,0">
                                <GradientStop Color="#FF9C1031" Offset="0.1"/>
                                <GradientStop Color="#FFBE0E20" Offset="0.2"/>
                                <GradientStop Color="#FF9C12AC" Offset="0.7"/>
                                <GradientStop Color="#FF0A8DC3" Offset="0.8"/>
                                <GradientStop Color="#FF1AEBCC" Offset="1"/>
                            </LinearGradientBrush>
                        </TextBlock.Foreground>
                        <TextBlock.Clip>
                            <EllipseGeometry x:Name="PART_EllipseGeometry">
                                <EllipseGeometry.Transform>
                                    <TranslateTransform/>
                                </EllipseGeometry.Transform>
                            </EllipseGeometry>
                        </TextBlock.Clip>
                    </TextBlock>
                </Canvas>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
```

三、SpotLightExample.Xaml 代码如下

<UserControl x:Class="WPFDevelopers.Samples.ExampleViews.SpotLightExample"
             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:WPFDevelopers.Samples.ExampleViews"
             xmlns:wpfdev="https://github.com/yanjinhuagood/WPFDevelopers"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <UniformGrid Rows="2">
        <wpfdev:SpotLight FontSize="50" Text="YanJinHua"/>
        <wpfdev:SpotLight/>
    </UniformGrid>
</UserControl>

更多教程欢迎关注微信公众号:

WPF开发者QQ群: 340500857

blogs: www.cnblogs.com/yanjinhua/p…

源码Githubgithub.com/yanjinhuago…

giteegitee.com/yanjinhua/W…

Github github.com/WPFDevelope…

码云 gitee.com/WPFDevelope…