[UWP]CompositionLinearGradientBrush加BlendEffect
admin
2023-02-15 05:40:05
0次

1. 什么是BlendEffect

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

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

[UWP]CompositionLinearGradientBrush加BlendEffect

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

[UWP]CompositionLinearGradientBrush加BlendEffect

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

[UWP]CompositionLinearGradientBrush加BlendEffect

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);

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

[UWP]CompositionLinearGradientBrush加BlendEffect

[UWP]CompositionLinearGradientBrush加BlendEffect

接下来创建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);

最终运行效果如下:

[UWP]CompositionLinearGradientBrush加BlendEffect

3. 创建动画

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

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);
}

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

[UWP]CompositionLinearGradientBrush加BlendEffect

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

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...