1. 什么是 CompositionBrush

CompositionBrush(合成画笔)是操作可视化层时用于绘制 SpriteVisual 区域的画笔。

使UWP 应用时可以选择使用 XAML 画笔CompositionBrush(合成画笔) 绘制 UIElement。很多时候XAML画笔和合成画笔都能实现同样的效果,在官方文档 使用 XAML 画笔 vs。CompositionBrush 这一节中有详细的对比介绍。

CompositionBrush性能更好且能做更复杂的动画。XAML Brush的能力是有极限的,我从短暂的UWP生涯当中学到一件事,XAML Brush越是玩弄动画,动画就越可能因为没有料到的事态而失败……除非超越XAML Brush。所以我不做XAML Brush动画啦。

2. 使用CompositionLinearGradientBrush

CompositionLinearGradientBrush 是线性渐变画笔,它是最基本的画笔之一,可以实现类似 LinearGradientBrush的效果。基本使用步骤如下:

  1. 通过Compositor创建CompositionLinearGradientBrush;
  2. 通过Compositor创建并配置CompositionColorGradientStop,然后添加到CompositionLinearGradientBrush的ColorStops里;
  3. 创建SpriteVisual并将它的Brush设置为CompositionLinearGradientBrush;
  4. 使用ElementCompositionPreview.SetElementChildVisual 将SpriteVisual设置到某个UIElement的可视化层里。

具体代码如下:

<Rectangle x:Name="Gradient"/>
var compositor = Window.Current.Compositor;

//创建 CompositionLinearGradientBrush。
var gradientBrush = compositor.CreateLinearGradientBrush();
gradientBrush.StartPoint = Vector2.Zero;
gradientBrush.EndPoint = new Vector2(1.0f); var blueGradientStop = compositor.CreateColorGradientStop();
blueGradientStop.Offset = 0f;
blueGradientStop.Color = Color.FromArgb(255, 43, 210, 255);
var redGradientStop = compositor.CreateColorGradientStop();
redGradientStop.Offset = 1f;
redGradientStop.Color = Color.FromArgb(255, 255, 43, 136);
gradientBrush.ColorStops.Add(blueGradientStop);
gradientBrush.ColorStops.Add(redGradientStop); //创建SpriteVisual并设置Brush
var backgroundVisual = compositor.CreateSpriteVisual();
backgroundVisual.Brush = gradientBrush; //将自定义 SpriteVisual 设置为元素的可视化树的最后一个子元素。
ElementCompositionPreview.SetElementChildVisual(Gradient, backgroundVisual); Gradient.SizeChanged += (s, e) =>
{
if (e.NewSize == e.PreviousSize)
return; //设置gradientBrush的尺寸
backgroundVisual.Size = e.NewSize.ToVector2();
gradientBrush.CenterPoint = backgroundVisual.Size / 2;
};

运行效果如下:

写了这么多代码,最终的效果其实和下面的XAML一样。

<Rectangle x:Name="Gradient">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="1,1" StartPoint="0,0">
<GradientStop Color="#FFFF2B88" Offset="1"/>
<GradientStop Color="#FF2BD2FF" Offset="0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>

到目前为止看起来CompositionBrush没什么优势。

3. 使用合成动画

其实CompositionBrush其中一个好玩的地方是灵活的合成动画。

要使用合成动画,简单来说就是三个步骤:

  1. 创建CompositionAnimation;
  2. 配置CompositionAnimation;
  3. 在要实现动画效果的CompositionObject及其属性上调用StartAnimation;

下面这段代码是对CompositionColorGradientStop的Offset属性进行动画:

//创建动画
var relaxGradientStopOffsetAnimation = _compositor.CreateScalarKeyFrameAnimation();
//配置动画
relaxGradientStopOffsetAnimation.Duration = TimeSpan.FromSeconds(1);
relaxGradientStopOffsetAnimation.InsertKeyFrame(1.0f, ViewModel.IsInPomodoro ?1.0f : 0.75f);
//运行动画
_relaxGradientStop.StartAnimation(nameof(_relaxGradientStop.Offset), relaxGradientStopOffsetAnimation);

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

4. 结语

其实上面的动画也可以用XAML画刷及Storyboard实现,但和这些技术已经老夫老妻了,再玩下去也没什么激情,所以想要玩点新花样。最近一直在搞番茄钟应用,有什么新的想法都会塞进去,可以在下面地址安装:

一个番茄钟

5. 参考

合成画笔 - Windows UWP applications _ Microsoft Docs

合成动画 - Windows UWP applications _ Microsoft Docs

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

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

ElementCompositionPreview.SetElementChildVisual(UIElement, Visual) Method (Windows.UI.Xaml.Hosting) - Windows UWP applications _ Microsoft Docs

6. 源码

OnePomodoro_Gradients.xaml.cs at master

[UWP]使用CompositionLinearGradientBrush实现渐变画笔并制作动画的更多相关文章

  1. [UWP]用Win2D和CompositionAPI实现文字的发光效果,并制作动画

    1. 成果 献祭了周末的晚上,成功召唤出了上面的番茄钟.正当我在感慨"不愧是Shadow大人,这难道就是传说中的五彩斑斓的黑?" "那才不是什么阴影效果,那是发光效果.& ...

  2. 前端制作动画的几种方式(css3,js)

    制作动态的网页是是前端工程师必备的技能,很好的实现动画能够极大的提高用户体验,增强交互效果,那么动画有多少实现方式,一直对此有选择恐惧症的我就总结一下,以便在开发的时候选择最好的实现方式. 1.css ...

  3. 如何用 Keynote 制作动画演示(转)

    原文:如何用 Keynote 制作动画演示 Keynote 里的很多特效可以用来制作效果不错的演示,一页页的将需要演示的内容交代清楚后,直接输出成 m4v 的视频格式,为了方便贴到博客或者发布到 Tw ...

  4. CSS3制作动画的三个属性

    CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation:我们一起学习完了Transform和Transition,让我们对元素实现了一些基本的动画效果,这 ...

  5. requestAnimationFrame制作动画:旋转风车

    在以往,我们在网页上制作动画效果的时候,如果是用javascript实现,一般都是通过定时器和间隔来实现的,出现HTML5之后,我们还可以用CSS3 的transitions和animations很方 ...

  6. canvas学习之制作动画

    html部分 ...... <body> <canvas id="myCanvas" width="400" height="400 ...

  7. html5 requestAnimationFrame制作动画:旋转风车

    详细内容请点击 在以往,我们在网页上制作动画效果的时候,如果是用javascript实现,一般都是通过定时器和间隔来实现的,出现HTML5之后,我们还可以用CSS3 的transitions和anim ...

  8. 在线Youtube视频下载,修改文本,剪切制作动画的最新方法

    刚刚(减去编写本文章的时间,大概20分钟前吧)在看国外最新技术资讯的时候发现有个方法可以让我们快速去下载Youtube上面的视频,不敢独享,我自己都没有怎么玩就所以立刻post上来广而告之,希望对大家 ...

  9. [UWP小白日记-9]页面跳转过度动画(二)

    又打算动手写了 [UWP小白日记-6]页面跳转过度动画 上次写的,这次随着学习的进度使用新的玩法. 最近在搞GIT的学习,结果把好好的项目玩坏,都不知道当时是怎么想的拿在写的APP来玩GIT,害我重写 ...

随机推荐

  1. UGUI_冻结技能键盘点击触发

    1.在某一张image图上添加Button组件,使其具有点击触发事件的功能: 2.outline组件 3.SkillItem脚本 using System.Collections; using Sys ...

  2. Winform中使用FastReport实现自定义PDF打印预览

    场景 Winform中使用FastReport实现简单的自定义PDF导出: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1009 ...

  3. Imageio: 'ffmpeg-win32-v3.2.4.exe' was not found on your computer; downloading it now.

    场景 在使用pip下载了Imageio之后,需要下载ffmpeag-win-32-v3.2.4.exe文件,一种是在代码的 开头部分加入: imageio.plugins.ffmpeg.downloa ...

  4. Tcloud 云测平台-多服务框架开源

    技术栈 Python3.7 + Vue前端github地址:https://github.com/bigbaser/Tcloud后端github地址:https://github.com/bigbas ...

  5. hibernate保存中文mysql

    最近自己做测试的时候,发现中文入库成?号了,不由得想到是否某处编码设置问题. 1.检查数据库是否为utf8 2.检查配置文件,数据库链接地址是否指定编码,经检查本地配置文件 jdbc.url=jdbc ...

  6. MySQL在Linux系统环境的安装和无主机登录配置

           将mysql 安装在单个Linux系统主机,并配置本地或远程(此处可仅单指局域状态下的环境)的无主机登录.谨记的是:操作完mysql 设置时,需以flush privileges进行权限 ...

  7. Python基础(十二)

    今日主要内容 推导式 生成器表达式 lambda匿名函数 内置函数介绍 一.推导式 (一)列表推导式 先来看一段代码 建立一个空列表,向空列表中添加元素 lst = list() for i in r ...

  8. Docker 网易镜像仓库使用

    Docker 网易镜像仓库使用: 网易账号注册: https://id.163yun.com/register?h=fc&referrer=https://console.163yun.com ...

  9. 包名targetPackage和目录名targetProject

    generatorConfig.xml中的 <javaModelGenerator targetPackage="edu.cn.pojo" targetProject=&qu ...

  10. bootstrap-table 页脚总计(自定义统计总数)

    •首先给table添加属性: showFooter: footer js代码如下: //初始化bootstrapTableinitBootstrapTable: function () { var o ...