动画文本,使字母循环

时间:2015-12-11 16:11:01

标签: c# wpf xaml

我有一个包含字母ABC的文本框。

我想做的是让信件流通。所以顺时针方向C将是开始圆圈的第一个字母然后因为C是绕B开始循环的一部分,然后是A.当C到达顶部时我希望它直到B&然后A回来让我们再次拥有ABC。然后重复 - 希望这是有道理的。

我的代码(大多数是复制的)如下。目前所发生的一切都是C做了一个圆然后停止&然后再去,但A& B似乎没有移动

C#

void StartTextAnimations(object sender, RoutedEventArgs e)
    {
        txtABC.TextEffects = new TextEffectCollection();

        Storyboard sbRotate = new Storyboard();
        sbRotate.RepeatBehavior = RepeatBehavior.Forever;
        sbRotate.AutoReverse = false;

        for (int i = 0; i < txtABC.Text.Length; i++)
        {
            AddTextEffectForCharacter(i);
            AddRotationAnimation(sbRotate, i);
        }

        Timeline pause = FindResource("CharacterRotationPauseAnimation") as Timeline;
        sbRotate.Children.Add(pause);

        sbRotate.Begin(this);            
    }

    void AddTextEffectForCharacter(int charIndex)
    {
        TextEffect effect = new TextEffect();

        effect.PositionStart = charIndex;
        effect.PositionCount = 1;

        TransformGroup transGrp = new TransformGroup();
        transGrp.Children.Add(new TranslateTransform());
        transGrp.Children.Add(new RotateTransform());
        effect.Transform = transGrp;

        txtABC.TextEffects.Add(effect);
    }

    void AddRotationAnimation(Storyboard sbRotate, int charIndex)
    {
        DoubleAnimation anim = FindResource("CharacterRotationAnimation") as DoubleAnimation;

        SetBeginTime(anim, charIndex);

        string path = string.Format("TextEffects[{0}].Transform.Children[1].Angle", charIndex);

        PropertyPath propPath = new PropertyPath(path);
        Storyboard.SetTargetProperty(anim, propPath);

        sbRotate.Children.Add(anim);
    }

    void SetBeginTime(Timeline anim, int charIndex)
    {
        double totalMs = anim.Duration.TimeSpan.TotalMilliseconds;
        double offset = totalMs / 10;
        double resolvedOffset = offset * charIndex;
        anim.BeginTime = TimeSpan.FromMilliseconds(resolvedOffset);
    }

XAML

        

    <DoubleAnimation
        x:Key="CharacterRotationAnimation"
        To="360"
        AccelerationRatio="0.5"
        DecelerationRatio="0.5"
        Duration="0:0:2"
        Storyboard.TargetName="txtABC"/>

    <DoubleAnimation
        x:Key="CharacterRotationPauseAnimation"
        Duration="0:0:8"
        Storyboard.TargetProperty="Opacity"/>        
</RibbonWindow.Resources>


<TextBlock Grid.Row="0" Grid.Column="2" Margin="10"
                x:Name="txtABC"
                Foreground="WhiteSmoke"
                Loaded="StartTextAnimations"
                Text="ABC"/>

1 个答案:

答案 0 :(得分:2)

问题在于,每次使用FindResource并且只是在实际中更改它的属性时,您将采用相同的双动画。你打算做的是对每个角色应用一个效果,这意味着每个角色都需要自己的DoubleAnimation实例。这是我使用的工作示例(改变了前景,所以我实际上可以看到dang的东西;)。)。

  • StartTextAnimations中:更改您的for循环,以便开始以正确的顺序应用动画,从“c”开始:

    //Reverse order applied
    for(int i = txtABC.Text.Length - 1; i >= 0; i--)
    {
        AddTextEffectForCharacter(i);
        AddRotationAnimation(sbRotate, i);
    }
    
  • 更改AddRotationAnimation以将动画应用于每个角色:

    void AddRotationAnimation(Storyboard sbRotate, int charIndex)
    {
        DoubleAnimation anim = new DoubleAnimation(0, 360, new Duration(new TimeSpan(0, 0, 0, 3))); //0 to 360 over 3 seconds
        Storyboard.SetTargetName(anim, "txtABC"); 
        SetBeginTime(anim, charIndex);
    
        string path = string.Format("TextEffects[{0}].Transform.Children[1].Angle", charIndex);
    
        PropertyPath propPath = new PropertyPath(path);
    
        Storyboard.SetTargetProperty(anim, propPath);
    
        sbRotate.Children.Add(anim);
    }
    
  • SetBeginTime中更改您的计算,以便字符不会相互重叠,

    void SetBeginTime(Timeline anim, int charIndex)
    {
        double totalMs = anim.Duration.TimeSpan.TotalMilliseconds;
        double offset = totalMs / 4.2; //slow, it, down.
        double resolvedOffset = offset * charIndex;
        anim.BeginTime = TimeSpan.FromMilliseconds(resolvedOffset);
    }
    

证明:

Rotating chars!