C# 轻松制作彩色动画

C# 轻松制作彩色动画,c#,uwp,uwp-xaml,windows-composition-api,C#,Uwp,Uwp Xaml,Windows Composition Api,我一直在下面的问题,使彩色动画 我可以创建动画,它运行良好,直到动画重新开始。有一段时间,它感觉动画已经在那里开始/停止了一段时间。我希望动画平稳运行,以便在颜色中不显示任何重新启动效果。有可能吗 我正在使用以下代码: <Storyboard x:Key="GradientAnimation" RepeatBehavior="Forever" Storyboard.TargetName="BackgroundB

我一直在下面的问题,使彩色动画

我可以创建动画,它运行良好,直到动画重新开始。有一段时间,它感觉动画已经在那里开始/停止了一段时间。我希望动画平稳运行,以便在颜色中不显示任何重新启动效果。有可能吗

我正在使用以下代码:

        <Storyboard x:Key="GradientAnimation"
                RepeatBehavior="Forever"
                Storyboard.TargetName="BackgroundBrush"
                SpeedRatio="0.3">
        <ColorAnimationUsingKeyFrames
            Storyboard.TargetProperty="(UIElement.Background).(LinearGradientBrush.GradientStops)[0].(GradientStop.Color)"
            EnableDependentAnimation="True"
            BeginTime="-0:0:0.5">

            <LinearColorKeyFrame KeyTime="0:0:0" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:1" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:2" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:3" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:4" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:5" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:6" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:7" Value="Red"/>

        </ColorAnimationUsingKeyFrames>
        <ColorAnimationUsingKeyFrames
            Storyboard.TargetProperty="(UIElement.Background).(LinearGradientBrush.GradientStops)[1].(GradientStop.Color)"
            EnableDependentAnimation="True">

            <LinearColorKeyFrame KeyTime="0:0:0" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:1" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:2" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:3" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:4" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:5" Value="Black"/>
            <LinearColorKeyFrame KeyTime="0:0:6" Value="Red"/>
            <LinearColorKeyFrame KeyTime="0:0:7" Value="Black"/>

        </ColorAnimationUsingKeyFrames>
    </Storyboard>

也许有某种“放松”方法混合了动画的开始和停止,使其看起来像长时间运行的动画一样平滑。有什么建议吗?

您可以尝试
EasingColorKeyFrame
,但动画永远不会平滑,因为它是在UI线程上运行的(即
EnableDependentAnimation=“True”

这里有一些好消息和坏消息。好的是,我们现在在合成层有了新的渐变笔刷API,这意味着它完全可以动画化,并且可以在UI线程中运行。因此,在性能方面,它将比当前的
情节提要
解决方案要好得多。但它只在Windows10InsiderPreview16225以后的版本中可用,这意味着除了内部人员之外,它对大多数当前用户都不起作用

不过,我还是要在这里发布这个新的解决方案,以供将来参考,因为还没有关于这个主题的示例

注意,我在动画中添加了一些额外的调味汁,使其更有趣。如果您只想对颜色设置动画,请随意移动
端点
旋转角度
动画(我使用
端点
动画在应用程序启动时将纯色背景设置为渐变,并使用
旋转角度
永远旋转渐变笔刷)

这是一个工作表,下面是它的外观:


我认为你只需要在开始的状态下完成。所以它可以是红色->黑色->红色。你说的“重新开始”是什么意思?它不是永远在运行吗?您是否手动停止并重新启动它?它一直在运行,是的,但它没有像需要的那样平滑,因为存在“间隙”之类的问题。在我最初的问题中,我只需从动画中删除
BeginTime
,即可使其平滑。但我真的很感激你的努力。
((Storyboard)Resources["GradientAnimation"]).Begin();
var compositor = Window.Current.Compositor;

// Initially, we set the end point to be (0,0) 'cause we want to animate it at start.
// If you don't want this behavior, simply set it to a different value within (1,1).
_gradientBrush = compositor.CreateLinearGradientBrush();
_gradientBrush.EndPoint = Vector2.Zero;

// Create gradient initial colors.
var gradientStop1 = compositor.CreateColorGradientStop();
gradientStop1.Offset = 0.0f;
gradientStop1.Color = GradientStop1StartColor;
var gradientStop2 = compositor.CreateColorGradientStop();
gradientStop2.Offset = 1.0f;
gradientStop2.Color = GradientStop2StartColor;
_gradientBrush.ColorStops.Add(gradientStop1);
_gradientBrush.ColorStops.Add(gradientStop2);

// Assign the gradient brush to the Root element's Visual.
_backgroundVisual = compositor.CreateSpriteVisual();
_backgroundVisual.Brush = _gradientBrush;
ElementCompositionPreview.SetElementChildVisual(Root, _backgroundVisual);

// There are 3 animations going on here.
// First, we kick off an EndPoint offset animation to create an special entrance scene.
// Once it's finished, we then kick off TWO other animations simultaneously. 
// These TWO animations include a set of gradient stop color animations and
// a rotation animation that rotates the gradient brush.

var linearEase = compositor.CreateLinearEasingFunction();
var batch = compositor.CreateScopedBatch(CompositionBatchTypes.Animation);
batch.Completed += (s, e) =>
{
    StartGradientColorAnimations();
    StartGradientRotationAnimation();
};
var endPointOffsetAnimation = compositor.CreateVector2KeyFrameAnimation();
endPointOffsetAnimation.Duration = TimeSpan.FromSeconds(3);
endPointOffsetAnimation.InsertKeyFrame(1.0f, Vector2.One);
_gradientBrush.StartAnimation(nameof(_gradientBrush.EndPoint), endPointOffsetAnimation);
batch.End();

void StartGradientColorAnimations()
{
    var color1Animation = compositor.CreateColorKeyFrameAnimation();
    color1Animation.Duration = TimeSpan.FromSeconds(10);
    color1Animation.IterationBehavior = AnimationIterationBehavior.Forever;
    color1Animation.Direction = AnimationDirection.Alternate;
    color1Animation.InsertKeyFrame(0.0f, GradientStop1StartColor, linearEase);
    color1Animation.InsertKeyFrame(0.5f, Color.FromArgb(255, 65, 88, 208), linearEase);
    color1Animation.InsertKeyFrame(1.0f, Color.FromArgb(255, 43, 210, 255), linearEase);
    gradientStop1.StartAnimation(nameof(gradientStop1.Color), color1Animation);

    var color2Animation = compositor.CreateColorKeyFrameAnimation();
    color2Animation.Duration = TimeSpan.FromSeconds(10);
    color2Animation.IterationBehavior = AnimationIterationBehavior.Forever;
    color2Animation.Direction = AnimationDirection.Alternate;
    color2Animation.InsertKeyFrame(0.0f, GradientStop2StartColor, linearEase);
    color1Animation.InsertKeyFrame(0.5f, Color.FromArgb(255, 200, 80, 192), linearEase);
    color2Animation.InsertKeyFrame(1.0f, Color.FromArgb(255, 43, 255, 136), linearEase);
    gradientStop2.StartAnimation(nameof(gradientStop2.Color), color2Animation);
}

void StartGradientRotationAnimation()
{
    var rotationAnimation = compositor.CreateScalarKeyFrameAnimation();
    rotationAnimation.Duration = TimeSpan.FromSeconds(15);
    rotationAnimation.IterationBehavior = AnimationIterationBehavior.Forever;
    rotationAnimation.InsertKeyFrame(1.0f, 360.0f, linearEase);
    _gradientBrush.StartAnimation(nameof(_gradientBrush.RotationAngleInDegrees), rotationAnimation);
}