之前突然要做一个这样的特效,本来以为网上大把,搜索下,直接用可以了,不过失望的是只找到一个模拟的那种,效果到是可以,不过缺点是,不能动态设置字,否则乱套;
没办法,只要写了一个,而且还要用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动态生成动画衔接就可以了~~自己琢磨吧