• WPF实现聚光灯效果


    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 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开发者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

  • 相关阅读:
    覆盖方法和重载方法 C++快速入门19
    访问控制 C++快速入门18
    继承机制中的构造器和析构器 C++快速入门17
    PEInfo编程思路讲解03 工具篇03|解密系列
    静态属性和静态方法 C++快速入门21
    PEInfo编程思路讲解03 工具篇03|解密系列
    继承机制中的构造器和析构器 C++快速入门17
    覆盖方法和重载方法 C++快速入门19
    linux系统中chmod命令
    linux系统中文件、目录的权限
  • 原文地址:https://www.cnblogs.com/yanjinhua/p/15391991.html
Copyright © 2020-2023  润新知