Chapter 51 · ShapeEx 进阶

Trim Path 路径裁剪

Trim Path 按百分比截取路径的一段进行绘制,是实现路径描边动画的核心技术。

51

概念

  • Begin / End:0.0 ~ 1.0 表示路径总长度的百分比区间。
  • Simultaneous:1 = 所有子路径同时裁剪;0 = 按顺序依次裁剪。
  • 典型用途:路径描边动画、进度环、手写效果。

API 速查

函数说明
int xgeShapeExTrimPath(xge_shape_ex pShape, float fBegin, float fEnd, int bSimultaneous)设置 Trim 区间
int xgeShapeExTrimPathGet(xge_shape_ex pShape, float* pBegin, float* pEnd, int* pSimultaneous, int* pEnabled)获取 Trim 参数
int xgeShapeExTrimClear(xge_shape_ex pShape)清除 Trim(恢复完整路径)

编译本章示例

gcc -O2 -I. -o ch51.exe ch51_main.c build\xge.lib -lm -lws2_32 -liphlpapi -lgdi32 -luser32 -lshell32 -lopengl32 -lole32 -lwinmm -lavrt
.\ch51.exe

示例 1:路径描边动画

static float s_fProgress = 0.0f;

void OnFrame(void) {
    s_fProgress += 0.005f;
    if (s_fProgress > 1.0f) s_fProgress = 0.0f;

    // 从 0% 到 progress% 绘制路径
    xgeShapeExTrimPath(g_shape, 0.0f, s_fProgress, 1);
    xgeShapeExDraw(g_shape, 0.25f);
}

示例 2:进度环

xge_shape_ex ring = NULL;
xgeShapeExCreate(&ring);
xgeShapeExAppendCircle(ring, 400, 300, 150, 150, 1);
xgeShapeExStrokeColor(ring, 0x4FD8C2FF);
xgeShapeExStrokeWidth(ring, 10.0f);
xgeShapeExStrokeCap(ring, XGE_SHAPE_EX_CAP_ROUND);

// 显示 75% 进度
xgeShapeExTrimPath(ring, 0.0f, 0.75f, 1);
xgeShapeExDraw(ring, 0.25f);

完整代码

将以下代码保存为 ch51_main.c,编译后运行即可看到 Trim Path 路径描边动画与进度环效果:

#include "xge.h"

static float s_fProgress = 0.0f;

static int onFrame(void* pUser) {
    (void)pUser;
    xgeClear(0x081114FF);

    s_fProgress += 0.005f;
    if (s_fProgress > 1.0f) s_fProgress = 0.0f;

    // 心形路径描边动画
    xge_shape_ex heart = NULL;
    xgeShapeExCreate(&heart);
    xgeShapeExMoveTo(heart, 400, 200);
    xgeShapeExCubicTo(heart, 400,160, 340,100, 280,140);
    xgeShapeExCubicTo(heart, 200,200, 280,320, 400,400);
    xgeShapeExCubicTo(heart, 520,320, 600,200, 520,140);
    xgeShapeExCubicTo(heart, 460,100, 400,160, 400,200);
    xgeShapeExStrokeColor(heart, 0xFF6B8AFF);
    xgeShapeExStrokeWidth(heart, 4.0f);
    xgeShapeExStrokeCap(heart, XGE_SHAPE_EX_CAP_ROUND);
    xgeShapeExTrimPath(heart, 0.0f, s_fProgress, 1);
    xgeShapeExDraw(heart, 0.25f);
    xgeShapeExDestroy(heart);

    // 进度环:75%
    xge_shape_ex ring = NULL;
    xgeShapeExCreate(&ring);
    xgeShapeExAppendCircle(ring, 400, 500, 60, 60, 1);
    xgeShapeExStrokeColor(ring, 0x4FD8C2FF);
    xgeShapeExStrokeWidth(ring, 8.0f);
    xgeShapeExStrokeCap(ring, XGE_SHAPE_EX_CAP_ROUND);
    xgeShapeExTrimPath(ring, 0.0f, 0.75f, 1);
    xgeShapeExDraw(ring, 0.25f);
    xgeShapeExDestroy(ring);
    return XGE_OK;
}

int main(void) {
    xge_desc_t d = {0};
    d.iWidth  = 800;
    d.iHeight = 600;
    d.sTitle  = "ch51 - Trim Path";
    d.iFlags  = XGE_INIT_VSYNC;
    xgeInit(&d);
    xgeRun(onFrame, NULL);
    xgeUnit();
    return 0;
}

代码讲解

  • TrimPath(begin, end):只绘制路径的 [begin, end] 比例区间,0~1 对应路径全长。
  • 描边动画:每帧增加 progress,实现“手写”效果。
  • 进度环:圆形路径 + Trim(0, 0.75) + Round Cap = 75% 进度指示器。
  • Simultaneous=1:多子路径时每个子路径独立裁剪同一比例。
  • TrimClear:清除 Trim 恢复绘制完整路径。

要点与陷阱

  • Begin < End:Begin 必须小于 End,否则无绘制输出。
  • 多子路径:Simultaneous=1 时每个子路径独立裁剪同一比例。
  • 清除:TrimClear 后恢复绘制完整路径。
  • 性能友好:Trim 不修改路径数据,仅影响绘制阶段。

进阶练习

  1. 实现"手写签名"动画:Bezier 路径 + 动态 Trim。
  2. 用 Begin/End 窗口滑动实现"彗星拖尾"效果。
Trim Path 路径裁剪效果
图:Trim Path 路径裁剪渲染效果