美文网首页.NET
[UWP]CompositionLinearGradientBr

[UWP]CompositionLinearGradientBr

作者: dino_chan | 来源:发表于2019-12-25 22:24 被阅读0次

    1. 什么是BlendEffect

    上一篇文章介绍了CompositionLinearGradientBrush的基本用法, 这篇文章再结合BlendEffec介绍一些更复杂的玩法。

    Microsoft.Graphics.Canvas.Effects命名空间下的BlendEffect 用于组合两张图片(分别是作为输入源的Background和Foreground),它包含多种模式,如下图所示:

    image

    其中最简单的是Screen模式,它的计算公式如下

    image

    看起来有点复杂, 我的理解是它相当于色轮中Background和Foreground之间拉直线,在直线的中间点的颜色,如下面这张图,红色和蓝色组合成为紫色:

    image

    2. 组合CompositionBrush并使用BlendEffect

    许多 CompositionBrushes 使用其他 CompositionBrushes 作为输入。 例如,使用 SetSourceParameter 方法可以将其他 CompositionBrush 设为 CompositionEffectBrush 的输入。这是CompositionBrush最好玩的地方之一。下面的例子介绍了怎么使用BlendEffect创建CompositionBrush。

    首先创建两个CompositionLinearGradientBrush:

    var foregroundBrush = compositor.CreateLinearGradientBrush();
    foregroundBrush.StartPoint = Vector2.Zero;
    foregroundBrush.EndPoint = new Vector2(1.0f);
    var redGradientStop = compositor.CreateColorGradientStop();
    redGradientStop.Offset = 0f;
    redGradientStop.Color = Color.FromArgb(255, 255, 0, 0);
    var yellowGradientStop = compositor.CreateColorGradientStop();
    yellowGradientStop.Offset = 1f;
    yellowGradientStop.Color = Color.FromArgb(255, 0, 178, 255);
    foregroundBrush.ColorStops.Add(redGradientStop);
    foregroundBrush.ColorStops.Add(yellowGradientStop);
    
    
    var backgroundBrush = compositor.CreateLinearGradientBrush();
    backgroundBrush.StartPoint = new Vector2(0, 1f);
    backgroundBrush.EndPoint = new Vector2(1f, 0);
    var blueGradientStop = compositor.CreateColorGradientStop();
    blueGradientStop.Offset = 0f;
    blueGradientStop.Color = Color.FromArgb(255, 0, 0, 255);
    var greenGradientStop = compositor.CreateColorGradientStop();
    greenGradientStop.Offset = 1f;
    greenGradientStop.Color = Color.FromArgb(255, 0, 255, 0);
    backgroundBrush.ColorStops.Add(blueGradientStop);
    backgroundBrush.ColorStops.Add(greenGradientStop);
    

    它们的效果分别如下面两张图片所示:

    image image

    接下来创建BlendEffect,并将Foreground和Background设置为CompositionEffectSourceParameter

    var blendEffect = new BlendEffect()
    {
        Mode = BlendEffectMode.Screen,
        Foreground = new CompositionEffectSourceParameter("Main"),
        Background = new CompositionEffectSourceParameter("Tint"),
    };
    

    使用BlendEffect创建Brush,并用SetSourceParameter设置它的Foreground和Background。

    var effectFactory = compositor.CreateEffectFactory(blendEffect);
    var blendEffectBrush = effectFactory.CreateBrush();
    blendEffectBrush.SetSourceParameter("Main", foregroundBrush);
    blendEffectBrush.SetSourceParameter("Tint", backgroundBrush);
    

    最后就是一般的使用这个blendEffectBrush的代码:

    //创建SpriteVisual并设置Brush
    var spriteVisual = compositor.CreateSpriteVisual();
    spriteVisual.Brush = blendEffectBrush;
    
    //将自定义 SpriteVisual 设置为元素的可视化树的最后一个子元素。
    ElementCompositionPreview.SetElementChildVisual(Gradient, spriteVisual);
    

    最终运行效果如下:

    image

    3. 创建动画

    和上一篇文章一样,我也把这篇文章用到的技术用在了一个番茄钟应用里,,简单地使用ColorKeyFrameAnimationScalarKeyFrameAnimation制作动画:

    private void StartOffsetAnimation(CompositionColorGradientStop gradientOffset, float offset)
    {
        var offsetAnimation = _compositor.CreateScalarKeyFrameAnimation();
        offsetAnimation.Duration = TimeSpan.FromSeconds(1);
        offsetAnimation.InsertKeyFrame(1.0f, offset);
        gradientOffset.StartAnimation(nameof(CompositionColorGradientStop.Offset), offsetAnimation);
    }
    
    private void StartColorAnimation(CompositionColorGradientStop gradientOffset, Color color)
    {
        var colorAnimation = _compositor.CreateColorKeyFrameAnimation();
        colorAnimation.Duration = TimeSpan.FromSeconds(2);
        colorAnimation.Direction = Windows.UI.Composition.AnimationDirection.Alternate;
        colorAnimation.InsertKeyFrame(1.0f, color);
        gradientOffset.StartAnimation(nameof(CompositionColorGradientStop.Color), colorAnimation);
    }
    

    完整代码在这里,具体运行效果如下:

    image

    4. 结语

    上面的动画可以安装我的番茄钟应用试玩一下,安装地址:

    一个番茄钟

    这篇文章的动画和代码都参考了JustinLiu的代码,感谢他的分享。

    使用XAML画笔难以做到这种多向渐变的效果,这都多亏了UWP提供了BlendEffect这个好玩的东西。BlendEffect还有很多其它好玩的模式,大家有空可以多多尝试。

    参考

    合成画笔 - Windows UWP applications _ Microsoft Docs

    BlendEffect Class

    BlendEffectMode Enumeration

    CompositionEffectBrush.SetSourceParameter(String, CompositionBrush) Method (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs

    CompositionEffectSourceParameter Class (Windows.UI.Composition) - Windows UWP applications _ Microsoft Docs

    源码

    OnePomodoro_GradientsWithBlend.xaml.cs at master

    相关文章

      网友评论

        本文标题:[UWP]CompositionLinearGradientBr

        本文链接:https://www.haomeiwen.com/subject/caphoctx.html