黑暗模式
5. 动画
本章导读:
一个炫酷的GUI界面是离不开动画的,通过使用动画给人用户眼前一亮的感觉。AWTK提供了多种动画机制,可以让GUI变得更加的形象、流畅。
5.1 简介
AWTK提供了两大类动画:窗口动画和控件动画,下面介绍如何使用这两种动画。
5.2 窗口动画
窗口动画是现代GUI最基本的功能之一,在窗口打开或关闭时,引入一个过渡动画,让用户感觉这个过程是流畅的。窗口动画的基本原理很简单:在打开或关闭窗口时,把前后两个窗口预先绘制到两张内存图片上,按照指定规则显示两张图片,形成动画效果。
5.2.1 动画类型
窗口本身只需指定期望的动画类型,由窗口管理器负责在适当的时候(如打开和关闭窗口时),创建窗口动画并让窗口动画绘制到屏幕上。在窗口动画期间,窗口管理器会禁止窗口本身的绘制,并忽略所有输入事件。目前支持的动画有:普通窗口动画和对话框动画。
- 普通窗口动画详见下表:
窗口动画类型 | 说明 |
---|---|
htranslate | 左右平移动画(速度最快,嵌入式平台推荐使用) |
vtranslate | 上下平移动画 |
slide_up | 向上弹出 |
slide_down | 向下弹出 |
slide_left | 向左弹出 |
slide_right | 向右弹出 |
- 对话框动画详见下表:
窗口动画类型 | 说明 |
---|---|
popup | 向上弹出(速度最快,嵌入式平台推荐使用) |
popdown | 向下弹出 |
fade | 淡入淡出动画 |
center_scale | 缩放动画(没有硬件时加速慎用) |
以前的bottom_to_top相当于popup,仍然可以使用,但建议用popup代替。以前的top_to_bottom相当于popdown,仍然可以使用,但建议用popdown代替。
5.2.2 使用方法
给窗口或对话框指定动画效果,只需设置窗口或对话框的anim_hint属性即可,代码如下:
xml
<window name="main" anim_hint="vtranslate">
...
</window>
5.2.3 动画参数
可以为动画指定参数,其格式为类似函数调用的参数格式。
(1)所有动画都支持下面的参数:
- duration 动画持续时间(毫秒)
- easing 插值算法名称
如:
xml
anim_hint="center_scale(duration=300)"
(2)slide_up、slide_down、slide_left和slide_right动画特有参数:
- start_alpha 起始alpha值(0-255)
- end_alpha 结束alpha值(0-255)
- alpha 相当于将start_alpha和end_alpha设置为同一个值
alpha值用于在背景上画一层透明的颜色,这能够实现让背景变暗的效果。如果start_alpha和end_alpha不相同,则能实现动态变暗的效果,这有额外的运行开销,如果性能不佳,建议设置alpha即可。
5.2.4 示例
给窗口或对话框指定动画效果,只需设置窗口或对话框的anim_hint属性即可,下面以awtk/bin/demoui.exe中的主界面main.xml为例,代码如下:
xml
<!-- awtk/demos/assets/default/raw/ui/main.xml -->
<window closable="no" text="Desktop" anim_hint="htranslate">
<slide_view x="0" y="0" w="100%" h="100%">
<view x="0" y="0" w="100%" h="100%" children_layout="default(c=2,r=8,m=5,s=5)">
<button name="open:basic" text="Basic"/>
<button name="open:button" text="Buttons"/>
<button name="open:edit" text="Edits"/>
<button name="open:keyboard" text="KeyBoard"/>
<button name="open:list_view" text="ListView"/>
<button name="open:slide_view" text="SlideView"/>
<button name="open:animation" text="Animate Window"/>
<button name="open:animator" text="Animate Widget"/>
<button name="open:tab_control" text="Tab Control"/>
<button name="open:combo_box" text="ComboBox"/>
<button name="open:rich_text" text="RichText"/>
<button name="open:color_picker" text="Color Picker"/>
</view>
...
</window>
还可以指定动画时长(duration,单位为毫秒),格式与函数调用类似,不过参数用name=value的形式,如:
xml
anim_hint="center_scale(duration=300)"
5.2.5 自定义动画
开发者可以自定义动画,自定义的动画可以像内置动画一样,在XML文件中启用。
自定义动画非常简单,通常只需要几行代码即可。步骤如下:
(1)实现window_animator_t接口。如:
c
static const window_animator_vtable_t s_window_animator_popup_vt = {
.overlap = TRUE,
.type = "popup",
.desc = "popup",
.size = sizeof(window_animator_t),
.draw_prev_window = window_animator_overlap_default_draw_prev,
.draw_curr_window = window_animator_to_top_draw_curr};
window_animator_t* window_animator_popup_create(bool_t open, object_t* args) {
return window_animator_create(open, &s_window_animator_popup_vt);
}
(2)注册到window_animator工厂。如:
c
window_animator_factory_register(factory, WINDOW_ANIMATOR_POPUP, window_animator_popup_create);
5.3 控件动画
控件动画是一种很常见的动画,常用于入场动画、离场动画、装饰用户界面和吸引用户注意力等。
5.3.1 动画类型
AWTK目前支持的控件动画类型详见下表:
控件动画类型 | 说明 |
---|---|
move | 通过改变控件位置形成动画效果 |
value | 通过改变控件值形成动画效果 |
opacity | 通过改变控件透明度形成动画效果 |
scale | 通过改变控件缩放比例形成动画效果(目前需要vgcanvas) |
rotation | 通过改变控件旋转角度形成动画效果(目前需要vgcanvas,draw_type为icon才能旋转) |
其它任何数值型的属性 | 如x/y/w/h等等 |
5.3.2 特色
- 支持逆向模式
- 支持停止和暂停
- 支持定时(延迟)执行
- 支持重复模式(可指定次数)
- 支持往返模式(可指定次数)
- 支持多种插值算法(如加速和减速等)
- 支持同一控件多个动画并行执行
- 支持同一控件多个动画串行执行
- 支持时间倍率,让时间变快和变慢
- 支持按名称去开始、暂停、停止和销毁动画
5.3.3 函数
AWTK提供了的函数接口详见下表,具体请查看AWTK_API手册。
函数名称 | 说明 |
---|---|
widget_animator_destroy | 销毁animator对象 |
widget_animator_init | 初始化仅供子类内部使用 |
widget_animator_off | 注销指定事件的处理函数 |
widget_animator_on | 注册指定事件的处理函数 |
widget_animator_pause | 暂停动画 |
widget_animator_set_destroy_when_done | 设置完成时是否自动销毁动画对象(缺省销毁) |
widget_animator_set_name | 设置名称 |
widget_animator_set_repeat | 设置为重复模式 |
widget_animator_set_reversed | 设置为逆向模式 |
widget_animator_set_time_scale | 设置时间倍率,用于实现时间加速减速和停滞的功能 |
widget_animator_set_yoyo | 设置为yoyo模式 |
widget_animator_start | 启动动画 |
widget_animator_stop | 停止动画 |
5.3.4 XML参数
1、公共参数,详见下表:
参数 | 说明 |
---|---|
name | 动画名称(缺省为动画的类型如move) |
delay | 延迟启动时间(毫秒) |
duration | 时长(毫秒) |
easing | 插值算法(见后面描述) |
yoyo_times | 往返的次数(x2),为0视为永久播放 |
repeat_times | 重复的次数,为0视为永久播放 |
auto_start | 创建后自动启动(缺省为true) |
auto_destroy | 完成后自动销毁(缺省为true) |
2、widget_animator_move动画的参数,详见下表:
参数 | 说明 |
---|---|
x_from | x起始位置 |
y_from | y起始位置 |
x_to | x结束位置 |
y_to | y结束位置 |
3、widget_animator_value动画的参数,详见下表:
参数 | 说明 |
---|---|
from | 起始值 |
to | 结束值 |
4、widget_animator_opacity动画的参数,详见下表:
参数 | 说明 |
---|---|
from | 起始值(0-255) |
to | 结束值(0-255) |
5、widget_animator_scale动画的参数,详见下表:
参数 | 说明 |
---|---|
x_from | x方向缩放起始值 |
y_from | y方向缩放起始值 |
x_to | x方向缩放结束值 |
y_to | y方向缩放结束值 |
6、widget_animator_rotation动画的参数,详见下表:
参数 | 说明 |
---|---|
from | 起始值(弧度) |
to | 结束值(弧度) |
7、其它数值型属性动画的参数,详见下表:
参数 | 说明 |
---|---|
from | 起始值 |
to | 结束值 |
5.3.5 插值算法名称(easing)
easing的类型和可取的值如下:
linear:
- linear
quadratic:
- quadratic_out
- quadratic_inout
cubic:
- cubic_in
- cubic_out
sin:
- sin_in
- sin_out
- sin_inout
pow:
- pow_in
- pow_out
- pow_inout
circular:
- circular_in
- circular_out
- circular_inout
elastic:
- elastic_in
- elastic_out
- elastic_inout
back:
- back_in
- back_out
- back_inout
bounce
- bounce_inout
- bounce_out
- bounce_inout
5.3.6 示例
既可以在UI文件的XML中,也可以使用C代码中创建动画,接下来将分别介绍如何在XML和C代码中创建动画。
1. 在XML中
在缺省情况下,动画创建后自动启动,完成后自动销毁。可以指定auto_start=false禁止创建后自动启动,指定参数auto_destroy=false禁止完成时自动销毁(控件销毁时仍然会自动销毁)。
在XML中可以使用animation参数创建动画,多个参数可以用";"分隔,此方法最为简单,后续可以在程序中通过动画名字,对动画进行启动和暂停等控制。下面以awtk/bin、demoui.exe中的AnimateWidget页面为例,代码如下:
xml
<!-- awtk/demos/assets/default/raw/ui/animator.xml -->
<window>
<image name="fade" image="logo" x="center" y="10" w="200" h="60" opacity="0"
animation="opacity(from=50, to=255, yoyo_times=1000, duration=1000)" />
<image name="fade" image="logo" x="center" y="80" w="200" h="60" opacity="0"
animation="opacity(from=50, to=255, yoyo_times=1000, duration=1000, delay=1000)" />
<image name="fade" image="logo" x="center" y="150" w="200" h="60" opacity="0"
animation="opacity(from=50, to=255, yoyo_times=1000, duration=1000, delay=2000)" />
<image name="move" image="logo" x="0" y="middle:60" w="200" h="60"
animation="move(x_from=0, x_to=200, yoyo_times=1000, duration=1000, delay=3000)"/>
<progress_bar name="value" x="center" y="middle" w="90%" h="40"
animation="value(from=50, to=100, yoyo_times=1000, duration=1000, delay=4000)"/>
<button name="close" x="center" y="bottom:10" w="25%" h="30" text="Close"/>
</window>
2. 在C代码中
在C代码中有两种方式创建动画,下面以awtk/bin/demo_animator.exe为例:
(1)采用widget_animator_xxx_create,其中xxx可取值move/value/opacity/scale/rotation,此方法比较麻烦,不再推荐使用,代码如下:
c
/* awtk/demos/demo_animator_app.c */
ret_t application_init() {
...
animator = widget_animator_move_create(image, 1000, delay, EASING_SIN_INOUT);
widget_animator_move_set_params(animator, image->x, image->y, image->x + 100, image->y + 100);
widget_animator_set_destroy_when_done(animator, FALSE);
widget_animator_set_repeat(animator, times);
widget_animator_start(animator);
...
}
(2)通过函数widget_create_animator创建动画,推荐使用,代码如下:
c
/* awtk/demos/demo_animator_app.c */
ret_t application_init() {
...
widget_create_animator(progress_bar, "value(from=50, to=100, duration=500, yoyo_times=1000, delay=1000)");
widget_create_animator(opacity, "opacity(to=50, duration=500, yoyo_times=1000)");
widget_create_animator(image6, "opacity(to=50, duration=500, yoyo_times=1000, delay=1000)");
widget_create_animator(image2, "rotation(to=6.28, yoyo_times=0, duration=1000, easing=sin_out)");
widget_create_animator(image3, "scale(x_to=-1, yoyo_times=1000, duration=1000, easing=sin_out)");
widget_create_animator(image4, "scale(x_to=2, y_to=2, yoyo_times=1000, duration=1000, easing=sin_out)");
widget_create_animator(image5, "y(to=400, duration=1000, easing=sin_out)");
widget_create_animator(image5, "opacity(to=0, duration=500, yoyo_times=1000, delay=1000)");
...
}