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**
**源码Github:https://github.com/yanjinhuagood/WPFDevelopers.git**
手机扫一扫
移动阅读更方便
你可能感兴趣的文章