在《一步一步学习使用FireMonkey动画(3)》中,介绍了TAnimation的多数子类,本节将对TRectAnimation、TPathAnimation和TBitmapListAnimation这3个子类进行介绍。
本节将介绍的主题如下:
- 使用TPathAnimation创建路径跟随的小球。
- 使用TBitmapListAnimation打造奔跑的小人动画
- 使用TRectAnimation打造内外边距移动动画
1. 使用TPathAnimation创建路径动画
TPathAnimation动画允许我们将目标控件沿一段矢量路径进行动画。在本系列的《一步一步学习使用FireMonkey动画(1)》中,演示了如何使用TPathAnimation的Path属性进行路径的绘制,例如类传如下的代码:
Pascal
PathAnimation1.Path.MoveTo(PointF(0, 0));
TPathAnimation 并不从 TCustomPropertyAnimation 继承,尽管它处理了目标对象的一些属性。处理的属性( Position 和 RotationAngle )只是硬编码到动画对象中。
TPathAnimation的Path属性接收矢量图形数据,可以在网站上找一些svg的矢量素材来使用,比如:
https://www.svgviewer.dev/
这个网站提供了很多的素材,可以复制Path路径中的路径数据,如下图所示:
下面以TPath组件为例,它的Path属性与TPathAnimation类似,它提供了一个可视化的编辑器,可以实时的查看矢量路径。
还可以使用svg编辑工具,比如InkScape,它完全免费且开源,可以在如下的网址下载:
https://inkscape.org/
可以使用这个工具绘制矢量图形,导出为svg格式的文件,这个文件是一个XML格式的文件,用记事本打开,复制其中的矢量路径到TPath或TPathAnimation的Path属性即可。
比如我在InkSacpe中使用钢笔工具随便画了一段线条:
接下来将其导出为svg文件,用记事本打开这个文件,将其d部分的属性值拷贝到TPath的Data属性中:
这样成功的得到了一条路径。
注意:FireMonkey 支持通过多个组件(如 TPath 、 TPath3D 和 TLabelPath )使用可缩放矢量图形(SVG)。这些组件都使用一个内部数据结构( TPathData ,定义在 FMX.Graphics 中),该结构可以解析和使用来自 SVG 定义的图形数据。
接下来新建一个Multi Deivce应用程序,使用空白模板,在主窗体上放一个TPath,然后将我们在《一步一步学习使用FireMonkey动画(3)》中创建的弹跳小球复制到本项目中。为弹跳小球添加一个TPathAnimation动画。
Structure结构如下所示:
分别为TPathAnimation的Path属性以及TPath的Data属性指定如下的路径数据:
M3.84500002861023,3.47300004959106 C4.83799982070923,24.6110000610352 26.2040004730225,34.9749984741211 42.875,30.8320007324219 C69.8730010986328,24.121000289917 82.1620025634766,-9.76099967956543 74.6009979248047,-37.4169998168945 C63.992000579834,-76.2160034179688 23.7210006713867,-93.3140029907227 -9.33600044250488,-80.4909973144531 C-52.2709999084473,-63.8380012512207 -70.8339996337891,-8.08600044250488 -55.2200012207031,37.6059989929199 C-35.9000015258789,94.1429977416992 24.3759994506836,118.28099822998 73.6240005493164,96.3960037231445 C132.567993164063,70.2020034790039 157.505996704102,-7.92000007629395 133.664993286133,-71.5500030517578 C105.81600189209,-145.880996704102 25.3040008544922,-177.113998413086 -40.0859985351563,-146.054992675781 C-95.6880035400391,-119.646003723145 -129.975997924805,-55.0750007629395 -127.064002990723,11.4790000915527
Path Designer窗口如下所示:
最后,在属性面板设置TPathAnimation动画属性:
除了AnimationType和Interpolation暂时还未详细介绍外,这里还有一个Rotate属性,该属性的意思是:
指定动画过程中对象是否旋转。使用 Rotate 属性可设定父控件在动画期间是否进行旋转。若将 Rotate 设置为 True,控件将进行旋转:正向动画时控件底部朝向路径方向,反向动画时控件顶部朝向路径方向。
运行动画,可以看到弹跳小球已经按照路径在运动。
仔细观察可以看到小球实际上是在旋转的。
最后来一个画蛇添足,为小球的运动添加一些轨迹,这里需要响应TPathAnimation的OnProcess事件,这个事件在每一次动画间隔(也就是每一帧刷新时)需要刷新动画显示时触发。
Pascal
private
{ Private declarations }
FDotPosition:TPointF; // 声明一个私有字段,用于存储上一次记录的点位置(TPointF类型,包含X和Y坐标)
public
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
{$R *.fmx}
procedure TfrmMain.PathAnimation1Process(Sender: TObject);
const CircleSize = 4; // 定义常量,表示绘制圆点的大小
begin
if FDotPosition.Distance(CircleBall.Position.Point) > CircleSize then // 判断当前球位置与上次记录点之间的距离是否大于圆点尺寸
begin
FDotPosition := CircleBall.Position.Point/2; // 计算新位置:将球当前位置坐标除以2(可能是为了缩小轨迹)
var LDot := TCircle.Create(Self); // 动态创建一个圆形控件(TCircle实例)
try
LDot.Parent := Self; // 设置圆形的父容器为当前窗体,使其显示在窗体上
LDot.Height := CircleSize; // 设置圆形的高度为预设的圆点尺寸
LDot.Width := CircleSize; // 设置圆形的宽度为预设的圆点尺寸
LDot.Position.Point := FDotPosition; // 将圆形定位到计算得到的新坐标位置
LDot.Position.Point.Offset(-CircleSize/2,-CircleSize/2); // 调整位置:将圆心偏移(-半径值),使绘制点以中心为基准(通常用于居中显示)
except
LDOt.Free; // 异常处理:如果创建或设置过程中发生错误,则释放已创建的圆形对象
end;
end;
end;
这样当弹跳小球沿路径运动时,会显示一个轨迹:
通过这个轨迹,可以发现,每一次动画的刷新时间似乎并不固定,这是由于不同的插值设置所影响的。
在后续的内容中会介绍动画的一些属性和事件的作用,敬请关注。
2. 使用TBitmapListAnimation打造奔跑的小人动画
这个控件让我们可以将一系列的连续的静态图片动起来,比如有下面的一幅图片:
TBitmapListAnimation通过将多个动画帧组合在一个图像条带中,然后按顺序快速切换这些帧来实现动画播放,非常适合处理那些不适合用矢量路径或属性插值实现的复杂动画(例如角色动画、特效等)。
它具有如下的一些新的属性:
- AnimationBitmap 设置源图像,包含所有动画帧的长条带状位图。
- AnimationCount 指定动画的总帧数。
- AnimationRowCount 指定源图像中动画的行数,常用于打包多组动画。
- PropertyName 指定要动画化的目标属性,对于序列帧动画,这通常是 Bitmap。
上面的图中,一共有5行图片,总共是30帧。
下面拉一个TRectangle控件到窗体,然后放一个TBitmapListAnimation在其上面,使TBitmapListAnimation的Parent指向TRectangle。
为TBitmapListAnimation的AnimationBitmap指定上面的图片,设置 AnimationCount为30,AnimationRowCount为5。
现在运行这个示例,可以看到小人已经在奔跑了。
是不是有一些电影小视频的效果了。
3. 使用TRectAnimation创建内外边距动画。
RectAnimation 是为了处理 FMX 视觉对象的 Padding 和 Margins 属性而引入的常见情况。这里涉及到的数据结构是 TBounds (定义在 FMX.Types 单元中),它是 FMX 中边距和填充的实际类型。
- Padding:是指控件的内边距,是控件边缘和内部的子元素之间的距离。
- Margins:是指控件的外边距,是控件的外边缘和其容器的边缘之间的距离。
它们均为TBound类型,具有Left、Top、Bottom、Right 4个属性,通过使用TRectAnimation,则可以创建内外边距的移动效果。
请在主窗体上拖一个TRectangle控件,拖一个TRectAnimation以它作为父项,在其内部再放一个TRectangle,指定其Align为Client,占满整个矩形。
为TRectAnimation设置如下的属性:
Pascal
AnimationType = InOut
AutoReverse = True
Enabled = True
Duration = 2
Interpolation = Exponential
Loop = True
PropertyName = 'Padding'
StopValue.Left = 50
StopValue.Top = 50
StopValue.Right = 50
StopValue.Bottom = 50
这里StartValue保持了默认的全是0,StopValue全部设置为50,PropertyName只能选择Margins和Padding,这里选择了Margins,现在运行动画,可以看到内边距果然产生了动画效果。
总结
本章介绍了3个有意思也是特别有创意的控件,一个是矢量路径动画TPathAnimation,一个是位图动画控件TBitmapListAnimation,还有一个内外边距变化的TRectAnimation控件,它们都可以创造出令人惊叹的动画效果。对于程序员来说,可能并不缺动画工具,而是缺那么一丝丝创意了。