昨夜飘风
昨 夜, 风, 飘 过; 枯 树, 叶, 飞 落。

之前突然要做一个这样的特效,本来以为网上大把,搜索下,直接用可以了,不过失望的是只找到一个模拟的那种,效果到是可以,不过缺点是,不能动态设置字,否则乱套;
没办法,只要写了一个,而且还要用C#来动态生成动画,麻烦了点,不过可以动态设置字体;
我作的是自定义控件来的,可以根据自己的需求,直接写道window里面去
先上XAML

<UserControl x:Class="WeatherDemo.myControl.Time"
             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;
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(000))));//添加时间线
                WidthMove.KeyFrames.Add(new EasingDoubleKeyFrame(-lenth, KeyTime.FromTimeSpan(new TimeSpan(000, (int)(lenth/50)))));
                storyboard.Children.Add(WidthMove);
            }

            storyboard.RepeatBehavior = RepeatBehavior.Forever;
            storyboard.Begin();
        }

       
    }


 MeasureTextWidth这个函数是动画能实现的关键地方,可以根据字体的大小类型来获取文字的长度,已经包装了,直接把TextBlock传进去就可以返回长度了,loadInfo记载数据并执行动画,中间一大片是做得通配符的识别,直接干掉就可以了~~~
 
另外上个比较粗糙的例子
 跑马灯
比较难看,不过功能Ok,有些人可以能需要无缝衔接的跑马灯,那就上2个txt动态生成动画衔接就可以了~~自己琢磨吧
 

posted on 2011-11-21 15:44  昨夜飘风  阅读(2813)  评论(0编辑  收藏  举报