WPF开发者QQ群: 340500857
前言
需要实现类似音乐播放器字幕滚动动画。
欢迎转发、分享、点赞,谢谢大家~。
效果预览(更多效果请下载源码体验):
一、TextBlockCustomControl.cs代码如下:
public class TextBlockCustomControl : TextBlock
{
public static readonly DependencyProperty DurationProperty =
DependencyProperty.Register("Duration", typeof(TimeSpan),
typeof(TextBlockCustomControl), new PropertyMetadata(TimeSpan.FromSeconds(1)));
public TimeSpan Duration
{
get { return (TimeSpan)GetValue(DurationProperty); }
set { SetValue(DurationProperty, value); }
}
public TimeSpan StartDuration
{
get { return (TimeSpan)GetValue(StartDurationProperty); }
set { SetValue(StartDurationProperty, value); }
}
public static readonly DependencyProperty StartDurationProperty =
DependencyProperty.Register("StartDuration", typeof(TimeSpan), typeof(TextBlockCustomControl), new PropertyMetadata(TimeSpan.FromSeconds(1)));
public TextBlockCustomControl()
{
NameScope.SetNameScope(this, new NameScope());
var gradientBrush = new LinearGradientBrush();
gradientBrush.EndPoint = new Point(1, 0.5);
gradientBrush.StartPoint = new Point(0, 0.5);
var stop1 = new GradientStop(Colors.White, 0);
var stop2 = new GradientStop(Colors.White, 1);
var stop3 = new GradientStop(Colors.Gray, 1);
this.RegisterName("GradientStop1", stop1);
this.RegisterName("GradientStop2", stop2);
this.RegisterName("GradientStop3", stop3);
gradientBrush.GradientStops.Add(stop1);
gradientBrush.GradientStops.Add(stop2);
gradientBrush.GradientStops.Add(stop3);
this.Foreground = gradientBrush;
this.Loaded += (s, e) =>
{
Animate();
};
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
}
private void Animate()
{
var storyboard = new Storyboard();
var animation1 = new DoubleAnimation();
animation1.From = 0;
animation1.To = 1;
animation1.Duration = Duration;
animation1.BeginTime = StartDuration;
Storyboard.SetTargetName(animation1, "GradientStop2");
Storyboard.SetTargetProperty(animation1,
new PropertyPath(GradientStop.OffsetProperty));
var animation2 = new DoubleAnimation();
animation2.From = 0;
animation2.To = 1;
animation2.Duration = Duration;
animation2.BeginTime = StartDuration;
Storyboard.SetTargetName(animation2, "GradientStop3");
Storyboard.SetTargetProperty(animation2,
new PropertyPath(GradientStop.OffsetProperty));
storyboard.Children.Add(animation1);
storyboard.Children.Add(animation2);
storyboard.Begin(this);
}
}
二、MainWindow.xaml代码如下:
<Window x:Class="WPFSongWords.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:shell="http://schemas.microsoft.com/winfx/2006/xaml/presentation/shell"
xmlns:local="clr-namespace:WPFSongWords"
mc:Ignorable="d"
Title="WPFDevelopers" Height="650" Width="400"
ResizeMode="NoResize" WindowStartupLocation="CenterScreen"
TextOptions.TextFormattingMode="Display" UseLayoutRounding="True"
SnapsToDevicePixels="True" WindowStyle="None" Background="Transparent"
Foreground="White" FontSize="14">
<Window.Resources>
<LinearGradientBrush x:Key="DefaultBackgroundBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#FF33B9AD" Offset="0" />
<GradientStop Color="#FF007ACC" Offset="1" />
</LinearGradientBrush>
</Window.Resources>
<shell:WindowChrome.WindowChrome>
<shell:WindowChrome GlassFrameThickness="-1" CaptionHeight="40"/>
</shell:WindowChrome.WindowChrome>
<Grid>
<Border Background="{StaticResource DefaultBackgroundBrush}"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
Margin="10">
<Border.Effect>
<DropShadowEffect ShadowDepth="1" BlurRadius="6" Direction="270" Opacity="0.75" Color="#FF211613"/>
</Border.Effect>
</Border>
<Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="60"/>
</Grid.RowDefinitions>
<Grid Height="40" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="WPF开发者" VerticalAlignment="Center"
Padding="10,0" FontSize="16"/>
<Button Grid.Column="1" Style="{StaticResource CloseButton}" Width="30"
Click="BtnCloseClick">
<Button.Content>
<Path Data="{StaticResource ClosePath}" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"
Height="12" Width="12" Stretch="Uniform" StrokeThickness="0"/>
</Button.Content>
</Button>
</Grid>
<StackPanel HorizontalAlignment="Center" Grid.Row="1">
<TextBlock Text="中华人民共和国国歌" HorizontalAlignment="Center" FontSize="20" Margin="0,10"/>
<ItemsControl ItemsSource="{Binding MusicWordArray,RelativeSource={RelativeSource AncestorType=local:MainWindow}}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:TextBlockCustomControl Text="{Binding SongWords}"
StartDuration="{Binding StarTime}"
Duration="{Binding RunTime}"
Block.TextAlignment="Center"
FontSize="15" Margin="0,4"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</Grid>
</Window>
三、MainWindow.xaml.cs代码如下:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WPFSongWords
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public IEnumerable MusicWordArray
{
get { return (IEnumerable)GetValue(MusicWordArrayProperty); }
set { SetValue(MusicWordArrayProperty, value); }
}
public static readonly DependencyProperty MusicWordArrayProperty =
DependencyProperty.Register("MusicWordArray", typeof(IEnumerable), typeof(MainWindow), new PropertyMetadata(null));
public MainWindow()
{
InitializeComponent();
this.Loaded += MainWindow_Loaded;
}
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
var musicWords = new List<MusicWord>();
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(1), StarTime = TimeSpan.FromSeconds(0), SongWords = "作词 : 田汉" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(1), StarTime = TimeSpan.FromSeconds(1), SongWords = "作曲 : 聂耳" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(0.5), StarTime = TimeSpan.FromSeconds(2), SongWords = "起来!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(2), StarTime = TimeSpan.FromSeconds(2.5), SongWords = "不愿做奴隶的人们!!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(4), StarTime = TimeSpan.FromSeconds(4.5), SongWords = "把我们的血肉,筑成我们新的长城!"});
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(3), StarTime = TimeSpan.FromSeconds(8.5), SongWords = "中华民族到了最危险的时候," });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(3.5), StarTime = TimeSpan.FromSeconds(11.5), SongWords = "每个人被迫着发出最后的吼声。" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(0.5), StarTime = TimeSpan.FromSeconds(15), SongWords = "起来!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(0.5), StarTime = TimeSpan.FromSeconds(15.5), SongWords = "起来!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(0.5), StarTime = TimeSpan.FromSeconds(16), SongWords = "起来!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(4.5), StarTime = TimeSpan.FromSeconds(16.5), SongWords = "我们万众一心,冒着敌人的炮火前进!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(2), StarTime = TimeSpan.FromSeconds(21), SongWords = "冒着敌人的炮火前进!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(0.5), StarTime = TimeSpan.FromSeconds(23), SongWords = "前进!" });
musicWords.Add(new MusicWord { RunTime = TimeSpan.FromSeconds(0.5), StarTime = TimeSpan.FromSeconds(23.5), SongWords = "前进!进!" });
MusicWordArray = musicWords;
}
private void BtnCloseClick(object sender, RoutedEventArgs e)
{
Close();
}
}
public class MusicWord
{
public TimeSpan RunTime { get; set; }
public TimeSpan StarTime { get; set; }
public string SongWords { get; set; }
}
}
更多教程欢迎关注微信公众号:
WPF开发者QQ群: 340500857
blogs: www.cnblogs.com/yanjinhua/p…
源码Github:github.com/yanjinhuago…
gitee:gitee.com/yanjinhua/W…