动画/视频编辑时间轴:图层/帧/Span 区间、帧率、标尺、选区、回调。
TimeLineView(注意大写 L)是专业时间轴控件:
• Layer:图层(轨道),可命名/着色/锁定/隐藏
• Frame:帧格子,可设置关键帧类型和 UserData
• Span:时间区间(片段),有起止帧和标签
• Ruler:顶部帧标尺
• Selection:帧/区间选择
注意:函数名为 xuiTimeLineView*(大写 L),desc 为 xui_timeline_view_desc_t。
| 函数 | 说明 |
|---|---|
int xuiTimeLineViewCreate(pCtx, ppW, pDesc) | 创建时间轴 |
int xuiTimeLineViewSetFrameCount(pW, iCount) | 总帧数 |
int xuiTimeLineViewSetFrameRate(pW, fRate) | 帧率 |
int xuiTimeLineViewSetCurrentFrame(pW, iFrame) | 当前帧 |
int xuiTimeLineViewAddLayer(pW, sName, pLayer) | 添加图层 |
int xuiTimeLineViewSetFrame(pW, iLayer, iFrame, iType, pUser) | 设置关键帧 |
int xuiTimeLineViewAddSpan(pW, iLayer, iStart, iEnd, iType, sLabel, pId) | 添加 Span |
int xuiTimeLineViewSetMetrics(pW, fHeaderW, fFrameW, fRowH, fRulerH) | 尺寸配置 |
int xuiTimeLineViewSetColors(pW, pColors) | 颜色配置 |
gcc -O2 -I. -o ch183.exe ch183_main.c src\xui_*.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch183.exe
xui_timeline_view_desc_t desc = { 0 };
xui_widget pTimeline;
xuiTimeLineViewCreate(pCtx, &pTimeline, &desc);
// 24fps,120 帧
xuiTimeLineViewSetFrameRate(pTimeline, 24.0f);
xuiTimeLineViewSetFrameCount(pTimeline, 120);
// 添加图层
int iPosLayer, iAlphaLayer;
xuiTimeLineViewAddLayer(pTimeline, "Position", &iPosLayer);
xuiTimeLineViewAddLayer(pTimeline, "Alpha", &iAlphaLayer);
// 设置关键帧
xuiTimeLineViewSetFrame(pTimeline, iPosLayer, 0, 1, NULL);
xuiTimeLineViewSetFrame(pTimeline, iPosLayer, 60, 1, NULL);
// 添加动画片段
int iSpan;
xuiTimeLineViewAddSpan(pTimeline, iAlphaLayer,
10, 50, 0, "FadeIn", &iSpan);
// 当前帧
xuiTimeLineViewSetCurrentFrame(pTimeline, 0);将以下代码保存为 ch183_main.c,编译后运行即可看到动画时间轴编辑器:
#include "xge.h"
#include "xui.h"
static xui_context g_pCtx;
static int onFrame(void* pUser) {
(void)pUser;
xgeClear(0x1E1E1EFF);
xui_vec2_t pos;
xgeMouseGet(&pos.x, &pos.y);
xuiInputPointerMove(g_pCtx, pos.x, pos.y);
if (xgeMouseDown(XGE_MOUSE_LEFT))
xuiInputPointerDown(g_pCtx, pos.x, pos.y, 0);
else
xuiInputPointerUp(g_pCtx, pos.x, pos.y, 0);
xuiUpdate(g_pCtx, xgeGetDelta());
xuiLayout(g_pCtx);
xuiRender(g_pCtx, NULL, NULL, 0);
return XGE_OK;
}
int main(void) {
xge_desc_t d = { 0 };
d.iWidth = 900; d.iHeight = 400;
d.sTitle = "ch183 - TimeLineView";
d.iFlags = XGE_INIT_VSYNC;
xgeInit(&d);
xuiCreate(&g_pCtx);
extern const xui_proxy_t tXgeProxy;
xui_proxy_t tXgeProxy = xuiProxyXge();
xuiSetProxy(g_pCtx, &tXgeProxy);
xuiSetViewportSize(g_pCtx, 900, 400);
// 创建时间轴
xui_timeline_view_desc_t tdesc = { 0 };
xui_widget pTL;
xuiTimeLineViewCreate(g_pCtx, &pTL, &tdesc);
// 24fps,120 帧
xuiTimeLineViewSetFrameRate(pTL, 24.0f);
xuiTimeLineViewSetFrameCount(pTL, 120);
// 添加图层
int iPos, iAlpha;
xuiTimeLineViewAddLayer(pTL, "Position", &iPos);
xuiTimeLineViewAddLayer(pTL, "Alpha", &iAlpha);
// 设置关键帧
xuiTimeLineViewSetFrame(pTL, iPos, 0, 1, NULL);
xuiTimeLineViewSetFrame(pTL, iPos, 60, 1, NULL);
xuiTimeLineViewSetFrame(pTL, iPos, 120, 1, NULL);
// 添加动画片段
int iSpan;
xuiTimeLineViewAddSpan(pTL, iAlpha,
10, 50, 0, "FadeIn", &iSpan);
xuiTimeLineViewSetCurrentFrame(pTL, 0);
xui_widget pRoot = xuiGetRootWidget(g_pCtx);
xuiWidgetAddChild(pRoot, pTL);
xuiWidgetSetRect(pTL, (xui_rect_t){0, 0, 900, 400});
xgeRun(onFrame, NULL);
xuiDestroy(g_pCtx);
xgeUnit();
return 0;
}