之前突然要做一个这样的特效,本来以为网上大把,搜索下,直接用可以了,不过失望的是只找到一个模拟的那种,效果到是可以,不过缺点是,不能动态设置字,否则乱套;
没办法,只要写了一个,而且还要用C#来动态生成动画,麻烦了点,不过可以动态设置字体;
我作的是自定义控件来的,可以根据自己的需求,直接写道window里面去
先上XAML
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"
mc:Ignorable ="d"
d:DesignHeight ="50" d:DesignWidth ="568" xmlns:my ="clr-namespace:WeatherDemo.myControl" >
< Canvas >
< my:RoundedRectangle Canvas.Left ="0" Canvas.Top ="1" Fill ="Black" Height ="50" x:Name ="roundedRectangle1" RadiusX ="10" RadiusY ="10"
RoundBottomLeft ="True" RoundBottomRight ="True" RoundTopLeft ="True" RoundTopRight ="True"
Stroke ="Black" Width ="568" />
< Border BorderBrush ="White" BorderThickness ="3" Height ="50" Name ="border1" Width ="568" CornerRadius ="5" >
< Border.Effect >
< DropShadowEffect Opacity ="0.85" ShadowDepth ="5" RenderingBias ="Quality" />
</ Border.Effect >
</ Border >
< Canvas Canvas.Left ="15" Width ="538" Name ="canva1" Height ="50" >
< Canvas.Clip >
< RectangleGeometry RadiusX ="0" RadiusY ="0" Rect ="10,0, 538,50" />
</ Canvas.Clip >
< TextBlock x:Name ="txt1" FontSize ="48" Foreground ="#FFFF3434" Text ="" Canvas.Top ="-3" Canvas.Left ="10" FontFamily ="宋体" >
< TextBlock.RenderTransform >
< TransformGroup >
< ScaleTransform />
< SkewTransform />
< RotateTransform />
< TranslateTransform />
</ TransformGroup >
</ TextBlock.RenderTransform >
</ TextBlock >
</ Canvas >
</ Canvas >
</ UserControl >
my:RoundedRectangle 是一个有弧边的Rectangle(有弧边的矩形),主要是为了好看,并且可以上底色,又需要可以做成玻璃效果,这里不谈这个
<TextBlock.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform />
</TransformGroup>
</TextBlock.RenderTransform >
这段必须有,否则C#添加动画出错,为什么,因为C#中使用了通用动画添加的方法,如果使用特定动画添加的函数,也可以不要这些,不过通用的方法比较直观,可以用blend作好后,对照XAML代码直敲C#的
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;
using System.Windows.Media.Animation;
namespace hoho.myControl
{
/// <summary>
/// Time.xaml 的交互逻辑
/// </summary>
public partial class Time : UserControl
{
// System.Timers.Timer timer = new System.Timers.Timer();
public Time()
{
InitializeComponent();
}
string runword = "";
public void loadInfo( string _runword)
{
runword = _runword;
runword = runword.Replace( " {date} ", DateTime.Now.Year.ToString() + " 年 " + DateTime.Now.Month.ToString() + " 月 " + DateTime.Now.Day.ToString() + " 号 ");
runword = runword.Replace( " {week} ", " 星期 " + " 日一二三四五六 ".Substring(( int)System.DateTime.Now.DayOfWeek.GetHashCode(), 1));
EcanChineseCalendar ChineseCalendar = new EcanChineseCalendar(DateTime.Now);
runword = runword.Replace( " {chinadata} ", ChineseCalendar.ChineseDateString); // "农历 " + ChineseCalendar.GanZhiDateString + " " + ChineseCalendar.ChineseMonthString +
txt1.Text = runword;
CeaterAnimation(txt1);
}
// 获取文字长度
private double MeasureTextWidth( string text, double fontSize, string fontFamily)
{
FormattedText formattedText = new FormattedText(
text,
System.Globalization.CultureInfo.InvariantCulture,
FlowDirection.LeftToRight,
new Typeface(fontFamily.ToString()),
fontSize,
Brushes.Black
);
return formattedText.WidthIncludingTrailingWhitespace;
}
private void CeaterAnimation(TextBlock text)
{
// 创建动画资源
Storyboard storyboard = new Storyboard();
double lenth = MeasureTextWidth(text.Text, text.FontSize, text.FontFamily.Source);
// 移动动画
{
DoubleAnimationUsingKeyFrames WidthMove = new DoubleAnimationUsingKeyFrames();
Storyboard.SetTarget(WidthMove, text);
DependencyProperty[] propertyChain = new DependencyProperty[]
{
TextBlock.RenderTransformProperty,
TransformGroup.ChildrenProperty,
TranslateTransform.XProperty,
};
Storyboard.SetTargetProperty(WidthMove, new PropertyPath( " (0).(1)[3].(2) ", propertyChain));//设置动画类型
WidthMove.KeyFrames.Add( new EasingDoubleKeyFrame(canva1.Width, KeyTime.FromTimeSpan( new TimeSpan( 0, 0, 0))));//添加时间线
WidthMove.KeyFrames.Add( new EasingDoubleKeyFrame(-lenth, KeyTime.FromTimeSpan( new TimeSpan( 0, 0, 0, ( int)(lenth/ 50)))));
storyboard.Children.Add(WidthMove);
}
storyboard.RepeatBehavior = RepeatBehavior.Forever;
storyboard.Begin();
}
}
}
MeasureTextWidth这个函数是动画能实现的关键地方,可以根据字体的大小类型来获取文字的长度,已经包装了,直接把TextBlock传进去就可以返回长度了,loadInfo记载数据并执行动画,中间一大片是做得通配符的识别,直接干掉就可以了~~~
另外上个比较粗糙的例子
跑马灯
比较难看,不过功能Ok,有些人可以能需要无缝衔接的跑马灯,那就上2个txt动态生成动画衔接就可以了~~自己琢磨吧