Loading动画控件
基本介绍
控件效果
一个滑动块来回运动的加载动画控件
控件接口
cpp
static void Loading(
const char *text, HVec2 pos, HVec2 wh,
unsigned int frameNums = 120,
ImVec4 color = ImVec4(0.9, 0.9, 0.9, 0.5),
ImVec4 background = ImVec4(0.2, 0.6, 0.9, 1)
)
- text: 控件文本
- pos: 控件(左上角)位置
- wh: 控件的宽和高
- frameNums: 控件滑动块移动动画单趟的帧数
- color: 滑动块的颜色
- background: 控件的底色/背景色
控件元素与动画
基本元素
- 一个矩形背景
- 一个文本
- 一个与背景等高的滑动块
动画
- 往返运动 的位移动画
设计与实现
基本元素
矩形背景
cpp
// Canvas()指向当前窗口区域
// draw bg
Canvas().addRectFilled(pos, pos + wh, ImColor(background));
使用pos作为左上顶点, pos + wh 作为右下顶点, background做为填充色绘制背景矩形
文本
cpp
// draw text
ImVec2 textSize = ImGui::CalcTextSize(text);
auto textPos = pos + HVec2{(wh.x - textSize.x) / 2, (wh.y - textSize.y) / 2};
ImGui::SetCursorPosX(textPos.x);
ImGui::SetCursorPosY(textPos.y);
ImGui::Text(text);
使用ImGui::CalcTextSize
获取文本的大小(包围盒的W和H), 用控件(背景矩形)的wh
计算出文本的相对坐标, 再加上控件坐标pos
, 得到最终的文本坐标textPos
获取文本坐标后, 使用ImGui::SetCursorPosX 和 ImGui::SetCursorPosY
设置文本控件坐标, 再使用ImGui::Text
进行显示(绘制)
滑动块
float blockWidth = wh.x * 0.2;
//....
Canvas().addRectFilled(pos, pos + HVec2{blockWidth, wh.y}, ImColor(color));
它和背景一样使用addRectFilled
绘制一个与背景矩形等高,且宽度为0.2倍(blockWidth
)的小的填充矩形, 但是这里滑动块的pos
需要动态更新, 下面将介绍动态更新方法。
位移动画与滑动块
cpp
auto anim = HEngine::AManager::registerAnimate<hanim::Move>(
pos, pos + HVec2{wh.x - blockWidth, 0},
HAnimate::Config {
.playType = hanim::HAnimate::PlayType::RT,
.frameNums = frameNums
}
);
使用HEngine::AManager::registerAnimate
注册一个移动动画, 从pos
到 pos + HVec2{wh.x - blockWidth, 0}
; 高度保持不变, 水平移动距离为控件的宽减去滑动块的宽度。
同时把动画的播放类型配置为PlayType::RT
,实现目标对象的往返运动
cpp
if (auto animPtr = anim.lock()) {
HEngine::PlayFrame(
*animPtr,
[ & ](int type, const hanim::IAFrame &frame) {
auto pos = HVec2{frame.data[0], frame.data[1]};
Canvas().addRectFilled(pos, pos + HVec2{blockWidth, wh.y}, ImColor(color));
}
);
}
这里使用HEngine::PlayFrame
把动画和滑动块进行结合, 生成按帧播放的动画
其中, *animPtr
为前面创建的移动动画 , [ & ](int type, const hanim::IAFrame &frame) {...}
为具体要渲染的对象, 根据每一帧到lambda表达式的插值动画数据实现动态的更新滑动块的坐标, 进而形成滑动块往返运动的效果
综合上面的代码, 就可以得到一个简单动画控件Loading的实现了
核心接口(API)列表
Hanim
接口 | 简述 |
---|---|
Canvas() | 对ImGui的drawList的封装, 简化当前窗口绘制区域的步骤 |
HEngine::AManager::registerAnimate | 用于进行注册并创建动画, 返回对应动画的指针(std::weak_ptr) |
arduino hanim::Move(pos1, pos2, config) |
创建位移动画的接口/对象 |
arduino HAnimate::Config |
动画基础属性配置类型 |
arduino HEngine::PlayFrame(animate, hobj) |
把anim动画作用到hobj对象上, 可以使用lambda表达式做为临时对象 |
arduino std::function<void (int, const IAFrame &)> |
插值动画lambda表达式的签名要求类型 |
ImGui
接口 | 简述 |
---|---|
DrawList->AddRectFilled(...) | 绘制带填充色的矩形 |
ImGui::CalcTextSize(text) | 计算文本的大小 |
ImGui::SetCursorPosX(.) / ImGui::SetCursorPosY(.) | 设置下一个控件的坐标(当前窗口坐标视为(0,0)) |
ImGui::Text(text) | 绘制文本 |
Other
文档仓库 github.com/Sunrisepeak/hanim-docs
在线文档 speaks-organization.gitbook.io/hanim+imgui-dong-hua-kong-jian-she-ji/