WPF实现聚光灯效果

  • A+
所属分类:.NET技术
摘要

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

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。

 

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

WPF实现聚光灯效果

 一、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 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"                     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"                     xmlns:controls="clr-namespace:WPFDevelopers.Controls">          <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> </Style>  </ResourceDictionary>

三、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实现聚光灯效果

WPF开发者QQ群: 340500857 

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

源码Github:https://github.com/yanjinhuagood/WPFDevelopers.git

gitee:https://gitee.com/yanjinhua/WPFDevelopers.git