[WPF] 玩玩彩虹文字及动画
1. 前言
兴致来了玩玩 WPF 的彩虹文字。不是用 LinearGradientBrush 制作渐变色那种,是指每个文字独立颜色那种彩虹文字。虽然没什么实用价值,但希望这篇文章里用 ItemsControl 拆分文字,以及用工具类提供递增和随机变量的做法可以给读者一些启发,就好了。
2. 用 TextBlock 的 Run
<TextBlock>
<Run Foreground="#4a0e68">b</Run>
<Run Foreground="#b62223">l</Run>
<Run Foreground="#fdd70c">o</Run>
<Run Foreground="#f16704">c</Run>
<Run Foreground="#69982d">k</Run>
<Run Foreground="#0075a5">.</Run>
<Run Foreground="#0b0045">R</Run>
<Run Foreground="#4a0e68">u</Run>
<Run Foreground="#b62223">n</Run>
</TextBlock>

用 TextBlock 的 Run 是做基本的做法,还有其它各种给 TextBlock 设置格式的方法,具体可以参考 text-block#formatting-text 这篇文档。
3. 写代码
这种方案就是用代码将字符串拆分,然后逐个字符塞进 TextBlock 然后放进 StackPanel,实现方式很无趣,我就不写了。
4. 用 ItemsControl
第三种方案是用 ItemsControl 实现,这个方案虽然会绕些弯路,但胜在够有趣,而且能扩展其它玩法。
首先,因为 string 是个集合,其实它可以用作 ItemsControl 的 ItemsSource。但在 Xaml 上直接写 ItemsSource="somestring"` 会报错,可以用 ContentControl 包装一下,写成这样:
<ContentControl Content="ItemsControl" >
<ContentControl.Template>
<ControlTemplate TargetType="ContentControl">
<ItemsControl ItemsSource="{TemplateBinding Content}" >
</ItemsControl>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
然后设置 ItemsControl 的 ItemsPanel,让内容横向排列;设置 DataTemplate,让拆分后的字符显示在 TextBlock 上:
<ItemsControl ItemsSource="{TemplateBinding Content}" >
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
接下来,为了让每个字符显示不同的颜色,需要实现一个 Collection 类并在 Xaml 上实例化它,将用到的颜色放进去:
<common:RepeatCollection x:Key="RepeatCollection">
<SolidColorBrush>#4a0e68</SolidColorBrush>
<SolidColorBrush>#b62223</SolidColorBrush>
<SolidColorBrush>#fdd70c</SolidColorBrush>
<SolidColorBrush>#f16704</SolidColorBrush>
<SolidColorBrush>#69982d</SolidColorBrush>
<SolidColorBrush>#0075a5</SolidColorBrush>
<SolidColorBrush>#0b0045</SolidColorBrush>
</common:RepeatCollection>
这个 RepeatCollection 的代码如下,它其实是个循环队列,每次调用 Next 的 getter 方法就拿下一个元素(叫 CircleCollection 会不会好些?):
public class RepeatCollection : Collection<object>
{
private int _offset;
public object Next
{
get
{
if (this.Count == 0)
return null;
var result = this[_offset];
_offset++;
if (_offset > this.Count - 1)
_offset = 0;
return result;
}
}
}
最后,TextBlock 的 Foreground 绑定到集合的 Next 属性,实现每一个 TextBlock 都使用不同的颜色:
<TextBlock Foreground="{Binding Next, Source={StaticResource RepeatCollection}}" Text="{Binding}" />

5. 动画
从第三种方案延申,我试玩了几种动画。
首先我写了个 TimeSpanIncreaser 类,它包含 Start、Setp、Next 三个属性,其中 Next 的代码如下:
public override TimeSpan Next => Start + (_current += Step);
它的作用就是每次调用 Next 属性,这个属性返回的值都递增。
回到 Xaml,首先在 Resources 中定义一个实例:
<common:TimeSpanIncreaser x:Key="TimeSpanIncreaser" Step="0:0:0.2" />
然后在 TextBlock 里加上这段:
<TextBlock.RenderTransform>
<TranslateTransform Y="-90" />
</TextBlock.RenderTransform>
<FrameworkElement.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="{Binding Next, Source={StaticResource TimeSpanIncreaser}}"
Storyboard.TargetName="TextElement"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
To="0"
Duration="0:0:0.7">
<DoubleAnimation.EasingFunction>
<BounceEase EasingMode="EaseOut" />
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</FrameworkElement.Triggers>
每个 TextBlock 使用相同的动画,但动画的开始时间是逐个递增的,运行起来效果如下:

再大胆些,ItemsControl 嵌套 ItemsControl,就可以做出下面这种效果:

又或者,这次不玩递增,玩随机。首先实现这两个类然后实例化,代码我就不贴出来了,看名字就能懂它们实现了什么功能:
<common:RandomColorCreator x:Key="RandomColorCreator" />
<common:RandomDoubleCreator x:Key="RandomDoubleCreator" Max="20" />
然后让 TextBlock 的 Foreground 和 TranslateTransform 动画的 X、Y 绑定到这两个实例的 Next 属性:
<TextBlock.Foreground>
<SolidColorBrush Color="{Binding Next, Source={StaticResource RandomColorCreator}}" />
</TextBlock.Foreground>
<TextBlock.RenderTransform>
<TranslateTransform />
</TextBlock.RenderTransform>
<FrameworkElement.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="TextElement"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
To="{Binding Next, Source={StaticResource RandomDoubleCreator}}"
Duration="0:0:.08" />
<DoubleAnimation AutoReverse="True"
RepeatBehavior="Forever"
Storyboard.TargetName="TextElement"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
To="{Binding Next, Source={StaticResource RandomDoubleCreator}}"
Duration="0:0:.1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</FrameworkElement.Triggers>
又一个毫无实用价值的动画诞生了:

6. 最后
虽然很遗憾没什么用,我只能安慰自己“结果不重要,最重要是享受过程”。
7. 源码
[WPF] 玩玩彩虹文字及动画的更多相关文章
- WPF学习之绘图和动画
如今的软件市场,竞争已经进入白热化阶段,功能强.运算快.界面友好.Bug少.价格低都已经成为了必备条件.这还不算完,随着计算机的多媒体功能越来越强,软件的界面是否色彩亮丽.是否能通过动画.3D等效果是 ...
- WPF学习之绘图和动画--DarrenF
Blend作为专门的设计工具让WPF如虎添翼,即能够帮助不了解编程的设计师快速上手,又能够帮助资深开发者快速建立图形或者动画的原型. 1.1 WPF绘图 与传统的.net开发使用GDI+进行绘图不 ...
- iOS—图片编辑,文字下落动画的Demo
仿照Mac上的截图编辑功能做的一个图片编辑的Demo,功能有画矩形,圆形,箭头,手写,输入文字和分享. 做的时候看到一个大神的帖子写的一个文字动画的教程,故顺带学习做了一个类似的文字下落动画. 有兴趣 ...
- WPF学习(12)动画
本篇来学习WPF的动画.什么是动画?动画就是一系列帧.在WPF中,动画就是在一段时间内修改依赖属性值的行为,它是基于时间线Timeline的.有人会说,要动画干嘛,华而不实,而且添加了额外的资源消耗而 ...
- 《深入浅出WPF》笔记——绘画与动画
<深入浅出WPF>笔记——绘画与动画 本篇将记录一下如何在WPF中绘画和设计动画,这方面一直都不是VS的强项,然而它有一套利器Blend:这方面也不是我的优势,幸好我有博客园,能记录一 ...
- WPF模拟探照灯文字
原文:WPF模拟探照灯文字 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/1835936 ...
- Canvas 3D球形文字云动画特效
Canvas 3D球形文字云动画特效 效果图: 代码如下,复制即可使用: (适用浏览器:360.FireFox.Chrome.Opera.傲游.搜狗.世界之窗. 不支持Safari.IE8及以下浏览器 ...
- 纯CSS3文字Loading动画特效
纯CSS3文字Loading动画特效是一款个性的loading文字加载动画. 在线演示本地下载
- WPF圆形环绕的Loading动画
原文:WPF圆形环绕的Loading动画 版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/yangyisen0713/article/details/ ...
随机推荐
- 鸿蒙内核源码分析(GN应用篇) | GN语法及在鸿蒙的使用 | 百篇博客分析OpenHarmony源码 | v60.01
百篇博客系列篇.本篇为: v60.xx 鸿蒙内核源码分析(gn应用篇) | gn语法及在鸿蒙的使用 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙 ...
- 深度学习|基于LSTM网络的黄金期货价格预测--转载
深度学习|基于LSTM网络的黄金期货价格预测 前些天看到一位大佬的深度学习的推文,内容很适用于实战,争得原作者转载同意后,转发给大家.之后会介绍LSTM的理论知识. 我把code先放在我github上 ...
- GDP区域分布图的生成与对比(ArcPy实现)
一.背景 各地区经济协调发展是保证国民经济健康持续稳定增长的关键.GDP是反映各地区经济发展状况的重要指标.科学准确分析各地区GDP空间分布特征,对制定有效措施,指导经济协调发展具有重要参考价值. 二 ...
- 洛谷4475 巧克力王国(KD-Tree + 维护子树和)
(嘤嘤嘤 又是一个自闭了一晚上的题) qwq果然不是平面上的点的问题,也可以直接用KDTree打暴力 我们对于巧克力直接建kdtree 维护一个\(mx[i],mn[i]\) 但是有一个非常不友好的事 ...
- 模拟赛T2 交换 解题报告
模拟赛T2 交换 解题报告 题目大意: 给定一个序列和若干个区间,每次从区间中选择两个数修改使字典序最小. \(n,m\) 同阶 \(10^6\) 2.1 算法 1 按照题意模拟,枚举交换位置并比较. ...
- Java(18)抽象类
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15201625.html 博客主页:https://www.cnblogs.com/testero ...
- NX7.5 使用UF_MODL_create_proj_curves创建投影曲线
1 [DllImport("libufun.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet ...
- python爬虫时,解决编码方式问题的万能钥匙(uicode,utf8,gbk......)
转载 原文:https://blog.csdn.net/xiongzaiabc/article/details/81008330 无论遇到的网页代码是何种编码方式,都可以用以下方法统一解决 imp ...
- javascript-jquery对象的动画处理
一.显示与隐藏动画效果 1.hide(动画持续时间,easing用来指定切换效果,动画执行完毕调用函数): $("p").hide(5000,"swing",f ...
- RabbitMQ延时队列应用场景
应用场景 我们系统未付款的订单,超过一定时间后,需要系统自动取消订单并释放占有物品 常用的方案 就是利用Spring schedule定时任务,轮询检查数据库 但是会消耗系统内存,增加了数据库的压力. ...