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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章