FEATURED · 精选文章

Bevy UI 圆角迁移指南:BorderRadius 字段变为 CornerRadius,ResolvedBorderRadius 变为 Vec2

发布时间 / 2026/9/6 16:34:39
来源 / 创域科博编辑部
栏目 / 资讯中心
Bevy UI 圆角迁移指南:BorderRadius 字段变为 CornerRadius,ResolvedBorderRadius 变为 Vec2 Bevy UI 圆角迁移指南BorderRadius 字段变为 CornerRadiusResolvedBorderRadius 变为 Vec2【免费下载链接】bevyA refreshingly simple>项目地址: https://gitcode.com/GitHub_Trending/be/bevy本篇指南围绕 Bevy UI 的一次破坏性 API 变更展开为支持椭圆elliptical圆角节点BorderRadius的四个角字段由Val变为CornerRadiusResolvedBorderRadius的字段由标量f32变为Vec2。读完本文你将掌握新旧 API 的逐项对照写法、CornerRadius的循环/椭圆语义与解析resolve规则并能顺畅地完成现有 UI 代码的迁移。背景为什么字段要变成二维官方迁移指南 border_radius.md对应 PR 24779给出的变更说明只有一句话In order to support elliptical nodes, the fields ofBorderRadiusare nowCornerRadiuss and the fields ofResolvedBorderRadiusare nowVec2s.即为了支持椭圆圆角节点BorderRadius的字段改为CornerRadiusResolvedBorderRadius的字段改为Vec2。对应的功能发布说明见 Elliptical Border Radius。在旧版 API 中每个角的圆角半径只有一个Val隐含圆形语义。新版允许 x水平与 y垂直半径不同从而画出一个椭圆的角。所有改动都集中在bevy_ui的两个文件里crates/bevy_ui/src/geometry.rs新增的CornerRadius类型crates/bevy_ui/src/ui_node.rsBorderRadius与ResolvedBorderRadius。迁移对照BorderRadius 的新旧写法变更前BorderRadius { pub top_left: px(10.), pub top_right: percent(20.), pub bottom_right: zero(), pub bottom_left: vh(5.), }变更后BorderRadius { pub top_left: CornerRadius::circular(px(10.)), pub top_right: CornerRadius::circular(percent(20.)), pub bottom_right: CornerRadius::circular(zero()), pub bottom_left: CornerRadius::circular(vh(5.)), }由于CornerRadius实现了FromVal见 geometry.rs你也可以用into完成同样的转换BorderRadius { pub top_left: px(10.).into(), pub top_right: percent(20.).into(), pub bottom_right: zero().into(), pub bottom_left: vh(5.).into(), }从源码结构看FromVal的实现是Self { x, y: auto() }即把原值放进x、y设为Val::Auto——这正好命中下一节讲的圆形表示。因此绝大多数只写圆形圆角的旧代码可以靠.into()最小改动地迁移。新类型 CornerRadius结构与圆形/椭圆语义CornerRadius的定义在 crates/bevy_ui/src/geometry.rspub struct CornerRadius { /// Responsive horizontal radius. pub x: Val, /// Responsive vertical radius. pub y: Val, }两个字段都是响应式的Val可以取px、percent、vh/vw、em/rem等任意响应式值。圆形圆角的表示方式Val::Auto迁移指南明确说明圆形圆角circular corner radius的表示方式是让CornerRadius::x或CornerRadius::y其中一个为Val::Auto。对应的构造辅助函数是circulargeometry.rs/// Creates a circular corner radius, with radius resolved relative to the nodes /// shortest side and clamped to half its length. pub const fn circular(radius: Val) - Self { Self { x: radius, y: Val::Auto, } }CornerRadius还提供了两组常量和两个常用构造器常量/方法定义语义CornerRadius::MAX{ x: Px(f32::MAX), y: Val::Auto }完全圆角半径为节点最短边的一半节点呈胶囊形宽高相等时为圆形CornerRadius::MAX_ELLIPTICAL{ x: Px(f32::MAX), y: Px(f32::MAX) }完全椭圆角水平半径为宽的一半垂直半径为高的一半节点被画成椭圆CornerRadius::ZERO{ x: ZERO, y: ZERO }直角circular(radius){ x: radius, y: Auto }圆形角半径相对节点最短边解析并钳制到其一半all(radius){ x: radius, y: radius }两轴同值。注意由于各轴独立解析percent 等值对宽高各自取值解析结果不一定相等new(x, y){ x, y }椭圆角分别指定水平/垂直半径一个容易踩的点是all与circular的区别。源码文档测试geometry.rs表明对 100x50 的节点all(px(30.))解析为Vec2::new(30., 25.)——x 轴钳制到宽度一半50y 轴钳制到高度一半25而circular(px(30.))会先对最短边50解析再钳制到 25得到Vec2::splat(25.)保证两轴严格相等、形状是圆弧而不是椭弧。可传入的输入类型From 实现一览BorderRadius的所有构造函数参数类型是impl IntoCornerRadius因此凡是可以转换为CornerRadius的类型都能传入。源码中提供了如下转换geometry.rsFromValpx(10.).into()等价于circularFrom(Val, Val)(px(10.), px(20.)).into()From[Val; 2][px(10.), px(20.)].into()。此外BorderRadius本身实现了FromT: IntoCornerRadiusui_node.rs直接调用Self::all(value)所以BorderRadius::from(px(10.))等于四角全圆角。一个值得注意的设计细节是PartialEq的实现geometry.rs{ x: v, y: Auto } { x: Auto, y: v }判定为相等。因为Auto只是另一轴未显式设置、按圆形半径解释的标记两种摆放方式语义相同。这意味着CornerRadius::circular(r)与{ x: r, y: auto() }、{ x: auto(), y: r }在比较时一致迁移后做assert_eq!时不必纠结Auto放在哪一轴。resolve解析成物理像素的规则CornerRadius::resolvegeometry.rs把响应式半径解析为物理像素Vec2签名与Val::resolve一致pub fn resolve( self, scale_factor: f32, size: Vec2, // 节点尺寸 viewport_size: Vec2, em_size: EmSize, rem_size: RemSize, ) - Vec2分支逻辑是两轴都是Auto→ 返回Vec2::ZERO一轴为Auto即圆形模式→ 用非 Auto 轴的值对节点最短边size.min_element()解析钳制到[0, 0.5 * min(size)]然后splat到两轴其余情况椭圆模式→ x 对size.x宽度解析、y 对size.y高度解析各自钳制到[0, 0.5 * size]。同文件的单元测试corner_radius_resolvegeometry.rs覆盖了这些行为100x50 节点上{x: Px(100.), y: Auto}解析为vec2(25., 25.)圆形钳制{x: Px(40.), y: Px(40.)}解析为vec2(40., 25.)椭圆钳制。这也印证了BorderRadius文档中半径若超过节点宽/高的一半会被计算为高/宽的一半的说明ui_node.rs。BorderRadius 构造器与更新函数不再 const迁移指南指出BorderRadius的构造函数和更新函数不再是const以便参数可以接受任意实现IntoCornerRadius的类型let n BorderRadius::top_right(vh(10.)); let m BorderRadius::top_right([px(10.), px(20.)]);实现上all、new、top_left/top_right/bottom_right/bottom_left、left/right/top/bottom以及with_*系列方法全部改为普通函数参数为impl IntoCornerRadiusui_node.rs。例如pub fn all(radius: impl IntoCornerRadius) - Self { let radius radius.into(); Self { top_left: radius, top_right: radius, bottom_left: radius, bottom_right: radius, } }两个例外值得注意px(f32, f32, f32, f32)与percent(f32, f32, f32, f32)这四个纯浮点参数的便捷构造器仍然是const fnui_node.rs因为它们内部直接写CornerRadius::circular(Val::Px(...))不经过Into转换。BorderRadius的常量同步扩展DEFAULT/ZERO直角、MAX胶囊/圆形、新增的MAX_ELLIPTICAL椭圆ui_node.rs。典型写法速查结合源码文档示例ui_node.rs四角混合圆角、圆角与椭圆角并存的完整写法是fn setup_ui(mut commands: Commands) { commands.spawn(( Node { width: Val::Px(100.), height: Val::Px(100.), border: UiRect::all(Val::Px(2.)), border_radius: BorderRadius { // 圆角x 和 y 半径相等 top_left: CornerRadius::circular(px(10.)), // FromVal 简写 top_right: percent(20.).into(), // 椭圆角 bottom_right: CornerRadius::new(px(30.), px(20.)), // 结构体字面量 bottom_left: CornerRadius { x: px(10.), y: px(40.) }, }, ..Default::default() }, BackgroundColor(BLUE.into()), )); }ResolvedBorderRadius解析结果从标量到 Vec2ResolvedBorderRadius是渲染侧消费的解析结果。变更后ui_node.rs/// The values are in physical pixels. pub struct ResolvedBorderRadius { pub top_left: Vec2, pub top_right: Vec2, pub bottom_right: Vec2, pub bottom_left: Vec2, }每个角是一个Vec2单位为物理像素x/y 分别对应水平/垂直半径BorderRadius::resolve只是对四角逐一调用CornerRadius::resolveui_node.rs签名包含scale_factor、node_size、viewport_size、em_size、rem_size该类型实现了FromResolvedBorderRadius for [[f32; 4]; 2]ui_node.rs把四个角摊平成第一行 4 个 x 半径、第二行 4 个 y 半径的二维数组从源码结构看这正是上传给 UI 渲染着色器的布局。bevy_ui_render中的节点矩形、文字、阴影等渲染模块都消费该类型。如果你之前直接读取ResolvedBorderRadius.top_left等字段做算术它曾是标量需要改为访问.x/.y分量。被移除的 APIresolve_single_corner迁移指南最后一项BorderRadius::resolve_single_cornerhas been removed, useCornerRadius::resolveinstead.即单角解析入口下移到了CornerRadius上参数为(scale_factor, size, viewport_size, em_size, rem_size)返回该角的物理像素Vec2。需要单角数值例如自定义裁剪矩形时直接对你感兴趣的那个CornerRadius字段调用resolve即可。迁移后的真实用法验证仓库中的示例与插件代码可以作为迁移后的参照UI 边框示例 examples/ui/styling/borders.rs 新增了四组椭圆圆角用例同时展示了三种写法结构体字面量CornerRadius { x: px(25), y: px(8) }、元组转换(px(8), px(25)).into()、数组转换[px(8), px(25)].into()以及percent半径的椭圆角控件库bevy_feathers的分段按钮圆角工具 rounded_corners.rs 中RoundedCorners::to_border_radius通过CornerRadius::from(px(radius))构造圆角再组合成BorderRadius——这是旧代码用From迁移的典型形态。迁移检查清单把BorderRadius四个角字段中的Val值包一层CornerRadius::circular(...)或.into()语义等价推荐.into()保持代码简洁构造器调用如BorderRadius::top_right(vh(10.))无需改动即可接受Val、(Val, Val)、[Val; 2]、CornerRadius任意类型需要椭圆角时传入两值即可若依赖了const上下文里调用all/with_*等需改为运行期调用纯px/percent常量构造仍可在const中使用读取ResolvedBorderRadius的地方改为Vec2分量运算删除对BorderRadius::resolve_single_corner的调用换成对应角上的CornerRadius::resolve。完成以上步骤后你的 UI 代码即兼容新版 Bevy 的椭圆圆角能力并且可以随时用CornerRadius::new(px(30.), px(20.))这类写法获得 CSSborder-radius风格的多值椭圆角效果。【免费下载链接】bevyA refreshingly simple>项目地址: https://gitcode.com/GitHub_Trending/be/bevy创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻