WPF实现聚光灯效果
阅读原文时间:2021年10月11日阅读: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。

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

一、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 代码如下

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

WPF开发者QQ群: 340500857

**blogs: https://www.cnblogs.com/yanjinhua/p/14345136.html**

**源码Githubhttps://github.com/yanjinhuagood/WPFDevelopers.git**

**giteehttps://gitee.com/yanjinhua/WPFDevelopers.git**

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器