ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Clay 图片元素如何保持原始宽高比?.image 与 .aspectRatio 配置详解

Clay 图片元素如何保持原始宽高比?.image 与 .aspectRatio 配置详解 Clay 图片元素如何保持原始宽高比.image 与 .aspectRatio 配置详解【免费下载链接】clayHigh performance UI layout library in C.项目地址: https://gitcode.com/GitHub_Trending/clay9/clay用 ClayC 语言的高性能 2D UI 布局库做界面时图片元素只要有一边使用动态尺寸就可能被拉伸变形。Clay 的解法是把图片元素拆成两个配置.image负责声明“这个元素要渲染一张图”.aspectRatio负责在布局阶段锁死元素的最终宽高比由 Clay 自动推导出缺失的那个维度。两者配合使用图片在随窗口缩放时就能保持原始比例。本文基于仓库README.md中Clay_ImageElementConfig/Clay_AspectRatioElementConfig两节文档、clay.h 的结构体定义以及官方示例examples/clay-official-website/main.c、examples/GLES3-SDL2-sidebar-scrolling-container/main.c的真实用法展开。先明确两个配置各自的作用.image 只声明图片不控制比例Clay_ImageElementConfig只有一个字段用来把图片数据透传给渲染器Clay_ImageElementConfig { void * imageData; };.imageData是普通的void *指针Clay 不解析它渲染命令输出时原样带回。README 给出的最小写法// Note that when rendering, .imageData will be void* type. CLAY(CLAY_ID(Image), { .image { .imageData profilePicture } }) {}.image的作用是“把元素配置成图片元素、输出一条 IMAGE 渲染命令”仅此而已。它不关心图片本身多大元素的尺寸完全由.layout.sizing决定。.aspectRatio 锁定最终宽高比Clay_AspectRatioElementConfig同样只有一个字段Clay_AspectRatioElementConfig { float aspectRatio; };clay.h 中的定义注释写明了含义A float representing the target Aspect ratio for an element, which is its final width divided by its final height.即aspectRatio 最终宽 / 最终高。16:9 的图片写16.0 / 9.0正方形图片写1。README 特别强调了一条关键规则位于 README.md 第二个Clay_ImageElementConfig小节的 NoteNote: for an image to maintain its original aspect ratio when using dynamic scaling, the [.aspectRatio] config option must be used.也就是说只写.image不写.aspectRatio的图片在动态尺寸下会按你给的.layout.sizing直接取尺寸比例由你手动保证想让它“自适应一边、锁定比例”必须显式配置.aspectRatio。让图片一边动态、一边自动推导保持原始宽高比的主路径是一边用CLAY_SIZING_GROW()参与布局、另一边交给比例推导。README 的官方示例文档示例// Load an image somewhere in your code YourImage profilePicture LoadYourImage(profilePicture.png); // Declare an image element that will grow along the X axis while maintaining its original aspect ratio CLAY(CLAY_ID(ProfilePicture), { .layout { .width CLAY_SIZING_GROW() }, .aspectRatio profilePicture.width / profilePicture.height, .image { .imageData profilePicture }, }) {}这里YourImage/LoadYourImage是文档中的伪代码类型名代表你自己的图片数据结构和加载函数aspectRatio取值为图片宽 / 图片高。宽度沿 X 轴增长CLAY_SIZING_GROW()无参数表示无上限高度由 Clay 按 1/比例 反推图片因此始终按原始比例显示。README 还给了内联配置的等价写法适合比例是已知常量如 16:9的场景CLAY(CLAY_ID(ImageInline), { .image { .imageData profilePicture }, .aspectRatio 16.0 / 9.0 }) {}Clay_AspectRatioElementConfig只有一个字段所以.aspectRatio 16.0 / 9.0会由 C 语言自动赋值到该结构体唯一的成员上显式写法.aspectRatio { .aspectRatio 16.0 / 9.0 }与之等价README 原文说明“C will automatically pass the value to the first nested struct field”。官方示例网站中的两张真实图片examples/clay-official-website/main.c 里Clay 官网的“语法”页放了一张竖版图对应仓库图片 declarative.png1136×1194写法如下CLAY(CLAY_ID(SyntaxPageRightImage), { .layout { .sizing { CLAY_SIZING_PERCENT(0.50) }, .childAlignment {.x CLAY_ALIGN_X_CENTER} } }) { CLAY(CLAY_ID(SyntaxPageRightImageInner), { .layout { .sizing { CLAY_SIZING_GROW(.max 568) } }, .aspectRatio { 1136.0 / 1194.0 }, .image { .imageData FrameAllocateString(CLAY_STRING(/clay/images/declarative.png)) } }) {} }宽度用CLAY_SIZING_GROW(.max 568)限制上限宽高比写死为1136.0 / 1194.0正是该 PNG 的像素宽/高。同一个文件里横版图debugger.png的对应写法main.cCLAY(CLAY_ID(DebuggerPageRightImageInner), { .layout { .sizing { CLAY_SIZING_GROW(.max 558) } }, .aspectRatio { 1620.0 / 1474.0 }, .image {.imageData FrameAllocateString(CLAY_STRING(/clay/images/debugger.png)) } }) {}侧边栏头像固定一边、比例补另一边examples/GLES3-SDL2-sidebar-scrolling-container/main.c 的“Photos”区域展示了另一种组合——固定宽度、比例 1 推导高度正方形头像CLAY(CLAY_ID(Picture2), {.layout {.sizing {.width CLAY_SIZING_FIXED(120)}}, .aspectRatio 1, .image {.imageData g_profilePicture}}) {}同一区域里还有完全不写.aspectRatio的对照写法main.cCLAY(CLAY_ID(ProfilePicture2), {.layout {.sizing {.width CLAY_SIZING_FIXED(60), .height CLAY_SIZING_FIXED(60)}}, .image {.imageData g_profilePicture}}) {}宽高都是CLAY_SIZING_FIXED(60)尺寸完全固定此时不需要比例推导这也说明.aspectRatio是给“有一边尺寸不确定”的元素用的。配置后的实际行为与渲染输出理解 Clay 何时计算比例可以避免误用。从 clay.h 的实现可以看到三处事实依据只有非 0 的.aspectRatio才生效。clay.h 中void Clay__UpdateAspectRatioBox(Clay_LayoutElement *layoutElement) { if (layoutElement-config.aspectRatio.aspectRatio ! 0) { if (layoutElement-dimensions.width 0 layoutElement-dimensions.height ! 0) { layoutElement-dimensions.width layoutElement-dimensions.height * layoutElement-config.aspectRatio.aspectRatio; } else if (layoutElement-dimensions.width ! 0 layoutElement-dimensions.height 0) { layoutElement-dimensions.height layoutElement-dimensions.width * (1 / layoutElement-config.aspectRatio.aspectRatio); } } }即aspectRatio为 0默认值未配置时不做任何比例处理只要某一边为 0、另一边已知就用比例补出另一边。布局过程中按两轴分步处理。clay.h 在 X 轴尺寸确定后对所有配置了比例的非文本元素执行height width / aspectRatioclay.h 在 Y 轴尺寸确定后再反向执行width aspectRatio * height。所以比例约束是在布局内部自动完成的你不需要每帧手动计算尺寸。渲染阶段只消费最终包围盒。READMEREADME.md说明元素经过可见性裁剪culling后会输出一条commandType CLAY_RENDER_COMMAND_TYPE_IMAGE的Clay_RenderCommand渲染器通过renderCommand-renderData.image.imageData取回布局时传入的图片指针renderCommand-renderData.image.backgroundColor与图片如何混合由渲染器自行决定。命令里的boundingBox就是 Clay 已经算好的最终尺寸所以比例约束体现在布局结果上而不是渲染时裁剪。验证方式据此很直接拿到该图片元素的渲染命令检查boundingBox的宽/高是否等于你写入的比例值例如1136.0 / 1194.0并且缺失的那一维已经被推导为非 0——这正是Clay__UpdateAspectRatioBox的补全结果。边界与限制比例必须非 0.aspectRatio为 0 表示未配置Clay 不会对元素做任何比例处理。想让图片保持比例必须显式写入width / height的浮点值。至少一边要能确定尺寸推导逻辑只在“一维为 0、另一维非 0”时补全另一边。如果宽、高都写成CLAY_SIZING_GROW()且父容器没有提供约束例如没有.max、没有百分比、父级尺寸未定推导无从触发上面的官方示例都通过.max、CLAY_SIZING_PERCENT或固定值给了一边约束照此配置即可。.aspectRatio不只用于图片README 说明它“Mostly used for image elements, but can also be used to enforce a fixed width / height ratio of other elements”非图片元素同样可用。比例不管渲染细节圆角裁剪走.cornerRadius色调/混合走renderData.image.backgroundColor是否显示走可见性裁剪这些与比例配置相互独立。图片加载与文字测量由外部提供Clay 本身不加载图片.imageData是透传指针文字测量需要Clay_SetMeasureTextFunction或 renderers/ 中各渲染器提供的实现这两步是搭建可运行环境的前提与本主题的正交部分不展开。完成配置后图片元素的最终尺寸由 Clay 布局直接给出GROW的一边参与父容器布局另一边由.aspectRatio推导渲染命令的boundingBox即为保持比例后的真实宽高。需要进一步调试时Clay 内置的调试工具Debug View会展示每个元素的Aspect Ratio配置值可用于确认比例是否按预期写入。【免费下载链接】clayHigh performance UI layout library in C.项目地址: https://gitcode.com/GitHub_Trending/clay9/clay创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表