- A+
所属分类:.NET技术
来瞧瞧,WPF 炫酷走马灯!
控件名:SpotLight
作者:WPFDevelopersOrg
-
框架使用大于等于
.NET40
; -
Visual Studio 2022
; -
项目使用 MIT 开源许可协议;
-
用Canvas做容器方便针对文本TextBlock做裁剪Clip动画操作;
-
Canvas内部创建两个TextBlock;
-
第一个做为背景字体设置字体颜色为浅灰
Foreground="#323232"
,也可以通过依赖属性设置DefaultForeground; -
第二个字体设置会彩虹色当聚光灯走到某个区域后并显示;
-
Duration可设置动画的从左到右的时长,默认3秒;
-
根据字体的实际宽度ActualWidth做动画展示从左到右并循环Forever播放;
1)SpotLight.cs 代码如下;
using System; 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"; public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(SpotLight), new PropertyMetadata("WPFDevelopers")); public static readonly DependencyProperty DefaultForegroundProperty = DependencyProperty.Register("DefaultForeground", typeof(Brush), typeof(SpotLight), new PropertyMetadata(new SolidColorBrush((Color)ColorConverter.ConvertFromString("#323232")))); public static readonly DependencyProperty DurationProperty = DependencyProperty.Register("Duration", typeof(TimeSpan), typeof(SpotLight), new PropertyMetadata(TimeSpan.FromSeconds(3))); private EllipseGeometry _ellipseGeometry; private TextBlock _textBlockBottom, _textBlockTop; static SpotLight() { DefaultStyleKeyProperty.OverrideMetadata(typeof(SpotLight), new FrameworkPropertyMetadata(typeof(SpotLight))); } public TimeSpan Duration { get => (TimeSpan)GetValue(DurationProperty); set => SetValue(DurationProperty, value); } public Brush DefaultForeground { get => (Brush)GetValue(DefaultForegroundProperty); set => SetValue(DefaultForegroundProperty, value); } public string Text { get => (string)GetValue(TextProperty); set => SetValue(TextProperty, value); } 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 { From = 0, To = _textBlockTop.ActualWidth, Duration = Duration }; 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.Begin(); } } }
2)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> <LinearGradientBrush x:Key="RainbowBrush" 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> <Style TargetType="{x:Type controls:SpotLight}" BasedOn="{StaticResource ControlBasicStyle}"> <Setter Property="Background" Value="#222222"/> <Setter Property="FontSize" Value="60"/> <Setter Property="FontFamily" Value="Arial Black"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="Foreground" Value="{StaticResource RainbowBrush}"/> <Setter Property="VerticalAlignment" Value="Center"/> <Setter Property="HorizontalAlignment" Value="Center"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type controls:SpotLight}"> <Grid x:Name="PART_Canvas" Background="{TemplateBinding Background}"> <TextBlock x:Name="PART_TextBlockBottom" Text="{TemplateBinding Text}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" FontWeight="{TemplateBinding FontWeight}" Foreground="{TemplateBinding DefaultForeground}"/> <TextBlock x:Name="PART_TextBlockTop" Text="{TemplateBinding Text}" FontSize="{TemplateBinding FontSize}" FontFamily="{TemplateBinding FontFamily}" FontWeight="{TemplateBinding FontWeight}" Foreground="{TemplateBinding Foreground}"> <TextBlock.Clip> <EllipseGeometry x:Name="PART_EllipseGeometry"> <EllipseGeometry.Transform> <TranslateTransform/> </EllipseGeometry.Transform> </EllipseGeometry> </TextBlock.Clip> </TextBlock> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </ResourceDictionary>
3)SpotLightExample.xaml代码如下如何使用;
<UniformGrid Rows="2" Background="#222222"> <wpfdev:SpotLight FontSize="50" Text="YanJinHua" DefaultForeground="Crimson" Foreground="Fuchsia" Duration="00:00:05" /> <wpfdev:SpotLight/> </UniformGrid>
SpotLight.cs|Github
SpotLight.cs|码云
SpotLight.xaml|Github
SpotLight.xaml|码云