feat(ibox): 实现信息弹窗背景自适应高度功能
1. 重构IBoxComp组件,移除旧的标题名称渲染逻辑 2. 添加动态背景节点,根据RichText内容自动调整高度 3. 优化cardbg和herobox预制体样式,调整尺寸与透明度 4. 新增通用背景预制体hbg,支持多配色快速复用 5. 重写ibox预制体结构,适配新的组件逻辑
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
* - SkillSet / FieldSkillSet(SkillSet)—— 技能/光环静态配置
|
||||
* - EquipSet(findEquipByUuid)—— 装备静态配置
|
||||
*/
|
||||
import { _decorator, Label, NodeEventType, RichText } from "cc";
|
||||
import { _decorator, Node, NodeEventType, RichText, UITransform, Widget } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||
import { SkillSet, SkillOverrides } from "../common/config/SkillSet";
|
||||
@@ -57,6 +57,15 @@ export class IBoxComp extends CCComp {
|
||||
@property(RichText)
|
||||
massage_node: RichText = null!
|
||||
|
||||
/** 背景节点(高度随 RichText 内容动态调整) */
|
||||
@property(Node)
|
||||
bg_node: Node = null!
|
||||
|
||||
/** Bg 节点高度上下留白(RichText 顶部间距 + 底部间距) */
|
||||
private static readonly BG_PADDING_V: number = 24;
|
||||
/** Bg 最小高度(防止内容过少时背景塌缩) */
|
||||
private static readonly BG_MIN_HEIGHT: number = 60;
|
||||
|
||||
/**
|
||||
* 初始化并渲染弹窗内容。
|
||||
* @param args 见 IBoxInitArgs
|
||||
@@ -92,23 +101,49 @@ export class IBoxComp extends CCComp {
|
||||
// 装备详情模式
|
||||
if (args?.equipUuid !== undefined) {
|
||||
this.renderEquip(args.equipUuid);
|
||||
return;
|
||||
}
|
||||
// 运行时技能详情模式(取第一个技能)
|
||||
if (args?.skills) {
|
||||
} else if (args?.skills) {
|
||||
// 运行时技能详情模式(取第一个技能)
|
||||
const first = Object.values(args.skills)[0];
|
||||
if (first) {
|
||||
this.renderSkill(first.uuid, first.lv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 技能详情模式
|
||||
if (args?.skillUuid !== undefined) {
|
||||
} else if (args?.skillUuid !== undefined) {
|
||||
// 技能详情模式
|
||||
this.renderSkill(args.skillUuid, args.skillLv ?? 1, args.overrides);
|
||||
return;
|
||||
} else {
|
||||
this.setRichText("暂无信息");
|
||||
}
|
||||
this.setHeroName("");
|
||||
this.setRichText("暂无信息");
|
||||
// RichText 排版需一帧完成,延迟同步 Bg 高度
|
||||
this.scheduleOnce(() => this.syncBgHeight(), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 RichText 实际内容高度,动态调整 Bg 节点高度与位置。
|
||||
* RichText 锚点已设为 (0.5, 1),从顶部向下生长;
|
||||
* Bg 锚点 (0.5, 0.5),向上居中扩展,顶部对齐 RichText 顶。
|
||||
*/
|
||||
private syncBgHeight() {
|
||||
if (!this.massage_node?.isValid) return;
|
||||
const richUT = this.massage_node.getComponent(UITransform);
|
||||
if (!richUT) return;
|
||||
|
||||
const contentH = Math.max(richUT.height, 0);
|
||||
const bgH = Math.max(contentH + IBoxComp.BG_PADDING_V, IBoxComp.BG_MIN_HEIGHT);
|
||||
|
||||
const bgNode = this.bg_node ?? this.node.getChildByName("bg");
|
||||
if (!bgNode?.isValid) return;
|
||||
const bgUT = bgNode.getComponent(UITransform);
|
||||
if (!bgUT) return;
|
||||
|
||||
// Bg 节点在 prefab 中挂了 Widget(顶底对齐),会覆盖代码设置的高度,先禁用
|
||||
const widget = bgNode.getComponent(Widget);
|
||||
if (widget) widget.enabled = false;
|
||||
|
||||
bgUT.height = bgH;
|
||||
// Bg 锚点在中心,高度为 bgH 时其中心应位于 RichText 顶部向下 bgH/2 处
|
||||
// RichText 锚点 (0.5,1),其顶部 y = pos.y;Bg 中心 y = pos.y - bgH/2
|
||||
const richPos = this.massage_node.node.position;
|
||||
bgNode.setPosition(bgNode.position.x, richPos.y - bgH / 2, bgNode.position.z);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,11 +155,9 @@ export class IBoxComp extends CCComp {
|
||||
private renderSkill(skillUuid: number, lv: number, overrides?: SkillOverrides) {
|
||||
const skill = SkillSet[skillUuid];
|
||||
if (!skill) {
|
||||
this.setHeroName("");
|
||||
this.setRichText("未知技能");
|
||||
return;
|
||||
}
|
||||
this.setHeroName(skill.name);
|
||||
this.setRichText(buildSingleSkillRich(skillUuid, overrides, lv));
|
||||
}
|
||||
|
||||
@@ -135,11 +168,9 @@ export class IBoxComp extends CCComp {
|
||||
private renderEquip(equipUuid: number) {
|
||||
const equip = findEquipByUuid(equipUuid);
|
||||
if (!equip) {
|
||||
this.setHeroName("");
|
||||
this.setRichText("未知装备");
|
||||
return;
|
||||
}
|
||||
this.setHeroName(equip.name);
|
||||
this.setRichText(buildEquipRich(equip.field ?? []));
|
||||
}
|
||||
|
||||
@@ -150,20 +181,6 @@ export class IBoxComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置标题名称标签
|
||||
* @param name 技能/装备名称
|
||||
*/
|
||||
private setHeroName(name: string) {
|
||||
const bgNode = this.node.getChildByName("Bg");
|
||||
const nameNode = bgNode?.getChildByName("name");
|
||||
const valNode = nameNode?.getChildByName("val");
|
||||
const label = valNode?.getComponent(Label) || valNode?.getComponentInChildren(Label);
|
||||
if (label) {
|
||||
label.string = name;
|
||||
}
|
||||
}
|
||||
|
||||
/** 点击弹窗任意区域关闭自身 */
|
||||
private onTapClose() {
|
||||
if (this.node && this.node.isValid) {
|
||||
|
||||
Reference in New Issue
Block a user