[UWP]组合CompositionBrush并使用BlendEffect
1. 什么是BlendEffect
上一篇文章介绍了CompositionLinearGradientBrush的基本用法, 这篇文章再结合BlendEffec介绍一些更复杂的玩法。
Microsoft.Graphics.Canvas.Effects命名空间下的BlendEffect 用于组合两张图片(分别是作为输入源的Background和Foreground),它包含多种模式,如下图所示:

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

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

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);
它们的效果分别如下面两张图片所示:


接下来创建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);
最终运行效果如下:

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);
}
完整代码在这里,具体运行效果如下:

4. 结语
上面的动画可以安装我的番茄钟应用试玩一下,安装地址:
这篇文章的动画和代码都参考了JustinLiu的代码,感谢他的分享。
使用XAML画笔难以做到这种多向渐变的效果,这都多亏了UWP提供了BlendEffect这个好玩的东西。BlendEffect还有很多其它好玩的模式,大家有空可以多多尝试。
参考
合成画笔 - Windows UWP applications _ Microsoft Docs
源码
OnePomodoro_GradientsWithBlend.xaml.cs at master
[UWP]组合CompositionBrush并使用BlendEffect的更多相关文章
- [UWP]CompositionLinearGradientBrush加BlendEffect,双倍的快乐
原文:[UWP]CompositionLinearGradientBrush加BlendEffect,双倍的快乐 1. 什么是BlendEffect# 上一篇文章介绍了CompositionLinea ...
- UWP 响应键盘组合快捷键
方法1:响应Ctrl+?快捷键 首先在load事件或者keydown事件内注册事件 public MainPage() { this.InitializeComponent(); // Registe ...
- [UWP]用Win2D和CompositionAPI实现文字的发光效果,并制作动画
1. 成果 献祭了周末的晚上,成功召唤出了上面的番茄钟.正当我在感慨"不愧是Shadow大人,这难道就是传说中的五彩斑斓的黑?" "那才不是什么阴影效果,那是发光效果.& ...
- [UWP]抄抄《CSS 故障艺术》的动画
1. 前言 什么是故障艺术(Glitch Art 风)?我们熟知的抖音的 LOGO 正是故障艺术其中一种表现形式.它有一种魔幻的感觉,看起来具有闪烁.震动的效果,很吸引人眼球.故障艺术它模拟了画面信号 ...
- New UWP Community Toolkit - XAML Brushes
概述 上一篇 New UWP Community Toolkit 文章中,我们对 V2.2.0 版本的重要更新做了简单回顾.接下来会针对每个重要更新,结合 SDK 源代码和调用代码详细讲解. 本篇我们 ...
- [UWP]使用AlphaMaskEffect提升故障艺术动画的性能(顺便介绍怎么使用性能探测器分析UWP程序)
前几天发布了抄抄<CSS 故障艺术>的动画这篇文章,在这篇文章里介绍了如何使用Win2D绘制文字然后配合BlendEffect制作故障艺术的动画.本来打算就这样收手不玩这个动画了,但后来又 ...
- MVVM框架从WPF移植到UWP遇到的问题和解决方法
MVVM框架从WPF移植到UWP遇到的问题和解决方法 0x00 起因 这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在W ...
- UWP简单示例(三):快速开发2D游戏引擎
准备 IDE:VisualStudio 2015 Language:VB.NET/C# 图形API:Win2D MSDN教程:UWP游戏开发 游戏开发涉及哪些技术? 游戏开发是一门复杂的艺术,编码方面 ...
- 【uwp】浅谈China Daily 中划词翻译的实现
学习uwp开发也有一段时间了,最近上架了一个小应用(China Daily),现在准备将开发中所学到的一些东西拿出来跟大家分享交流一下. 先给出应用的下载链接:China Daily , 感兴趣的童鞋 ...
随机推荐
- 有关Spring事务,看这一篇就足够了
本文将按照声明式事务的五个特性进行介绍: 事务传播机制 事务隔离机制 只读 事务超时 回滚规则 Spring事务传播机制 事务的特性 原子性(Atomicity):事务是一个原子操作,由一系列动作组成 ...
- Mysql学习笔记整理之选用B+tree结构
为什么mysql不使用平衡二叉树? 数据处的深度决定着他的IO操作次数,IO操作耗时大 每一个磁盘块保存的数据量太小 B+Tree和B-Tree的区别? B+树几点关键字搜索采用闭合区间 B+树非叶节 ...
- el-table合并行并自定义某一列或几列
在el-table的官方组件中并没有看到具体的合并行或者列及自定义表格内容,于是就自己写了一个效果如下所示. 这种对左侧内容要求比较高,要求行合并,并要自定义一些内容.下面说一下具体方法及代码写法. ...
- 2019windows上安装Mac OS 10.14过程详细截图
之前VMware12里面的Mac OS10.10升级后,键盘鼠标就用不了了.试了几次都这样,只能重装VMware14, 安装Mac OS 10.14系统.把步骤截下图,分享一下. 一.材料准备 1.虚 ...
- FTP无法登录问题-内有网盘福利
http://dinghuqiang.blog.51cto.com/19871/701185/ 一顿操作猛如虎,还是没解决. 然后我想想,会不会是浏览器缓存问题? 换个火狐登录看看! 哇擦!看到报错了 ...
- mybatis 配置之<typeAliases>别名配置元素设置
一.方式一:使用typeAlias <typeAliases> <typeAlias alias="User" type="com.**.entity. ...
- jenkins+svn+Ant+tomcat+非maven项目构建
首先,输入项目名称,创建一个自由风格的项目; 然后,配置旧项目的策略参数,目的是防止构建项目太多,占用资源. 下一步,jdk版本选择: 下一步,关联svn项目. 下一步:配置ant 看不清,再来一张. ...
- C++之路 #1
一.C++介绍C++是C语言的继承,它可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计.C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计 ...
- Vue-懒加载(判断元素是否在可视区域内)
上公式: 元素距离顶部高度(elOffsetTop) >= dom滚动高度(docScrollTop) 并且元素距离顶部高度(elOffsetTop) < (dom滚动高度 + 视窗高度) ...
- 从零开始的vue学习笔记(七)
前言 今天花一天时间阅读完vuex的官方文档,简单的做一下总结和记录 Vuex是什么 Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式,以前的符合"单向数据流"理念的 ...