perf: 优化通关弹窗进度条

This commit is contained in:
richarjiang
2026-05-06 21:54:25 +08:00
parent 06238f933b
commit 106da584e8
3 changed files with 861 additions and 118 deletions

View File

@@ -1441,7 +1441,7 @@
"_lpos": {
"__type__": "cc.Vec3",
"x": 0,
"y": 80.73400000000004,
"y": 67.20500000000004,
"z": 0
},
"_lrot": {
@@ -1850,11 +1850,11 @@
"__prefab": {
"__id__": 78
},
"_alignFlags": 4,
"_alignFlags": 1,
"_target": null,
"_left": 0,
"_right": 0,
"_top": 733.9639999999999,
"_top": 720.295,
"_bottom": 868.234,
"_horizontalCenter": 0,
"_verticalCenter": 0,
@@ -1865,7 +1865,7 @@
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_originalHeight": 650,
"_alignMode": 2,
"_lockFlags": 0,
"_id": ""
@@ -1883,8 +1883,6 @@
"__id__": 0
},
"fileId": "52Z4d22QhI1rhPunFg8yFm",
"instance": null,
"targetOverrides": null,
"nestedPrefabInstanceRoots": null
},
{
@@ -6187,11 +6185,11 @@
"__prefab": {
"__id__": 256
},
"_alignFlags": 4,
"_alignFlags": 1,
"_target": null,
"_left": 0,
"_right": 0,
"_top": 0,
"_top": 1396.401,
"_bottom": 663.5989999999999,
"_horizontalCenter": 0,
"_verticalCenter": 0,
@@ -6202,7 +6200,7 @@
"_isAbsHorizontalCenter": true,
"_isAbsVerticalCenter": true,
"_originalWidth": 0,
"_originalHeight": 0,
"_originalHeight": 100,
"_alignMode": 2,
"_lockFlags": 0,
"_id": ""

File diff suppressed because it is too large Load Diff

View File

@@ -59,6 +59,10 @@ export class PassModal extends BaseModal {
@property(Label)
progressLabel: Label | null = null;
/** 称号进度游标 */
@property(Node)
progressAnchor: Node | null = null;
/** 通关音效 */
@property(AudioClip)
successAudio: AudioClip | null = null;
@@ -89,6 +93,9 @@ export class PassModal extends BaseModal {
/** 进度动画所绑定的对象,用于 Tween.stopAllByTarget */
private readonly _progressTweenTarget: { progress: number } = { progress: 0 };
/** 进度游标 0% 时的本地 X 坐标,使用 prefab 当前摆放位置作为起点 */
private _progressAnchorStartX: number | null = null;
setParams(params: PassModalParams): void {
super.setParams(params);
@@ -125,6 +132,8 @@ export class PassModal extends BaseModal {
*/
onViewLoad(): void {
console.log('[PassModal] onViewLoad');
this._resolveProgressAnchor();
this._cacheProgressAnchorStartX();
this._bindButtonEvents();
}
@@ -234,9 +243,11 @@ export class PassModal extends BaseModal {
}
private _applyProgressValue(progress: number | undefined): void {
if (this.titleProgressBar && progress !== undefined) {
this.titleProgressBar.progress = this._normalizeProgress(progress);
if (progress === undefined) {
return;
}
this._applyAnimatedProgress(progress);
}
/**
@@ -292,9 +303,7 @@ export class PassModal extends BaseModal {
const clampedEnd = Math.max(0, Math.min(1, endProgress));
const onUpdate = () => {
if (self.titleProgressBar?.isValid) {
self.titleProgressBar.progress = self._normalizeProgress(tweenTarget.progress);
}
self._applyAnimatedProgress(tweenTarget.progress);
};
tween(tweenTarget)
@@ -309,9 +318,7 @@ export class PassModal extends BaseModal {
self._applyTitleText(self._titleInfo.titleText);
self._applyProgressText(self._titleInfo.progressText);
tweenTarget.progress = 0;
if (self.titleProgressBar?.isValid) {
self.titleProgressBar.progress = self._normalizeProgress(0);
}
self._applyAnimatedProgress(0);
})
.delay(PassModal.PROGRESS_ANIM_LEVELUP_PAUSE)
.to(
@@ -329,8 +336,8 @@ export class PassModal extends BaseModal {
const tweenTarget = this._progressTweenTarget;
// raw 值保留 0~1 区间onUpdate 里经 _normalizeProgress 再下发,避免畸变区段
tweenTarget.progress = Math.max(0, Math.min(1, from));
this.titleProgressBar.progress = this._normalizeProgress(from);
tweenTarget.progress = this._clampProgress(from);
this._applyAnimatedProgress(from);
const self = this;
const chain = tween(tweenTarget);
@@ -345,15 +352,67 @@ export class PassModal extends BaseModal {
{
easing: 'sineOut',
onUpdate: () => {
if (self.titleProgressBar?.isValid) {
self.titleProgressBar.progress = self._normalizeProgress(tweenTarget.progress);
}
self._applyAnimatedProgress(tweenTarget.progress);
}
}
)
.start();
}
private _cacheProgressAnchorStartX(): void {
if (this._progressAnchorStartX !== null || !this.progressAnchor) {
return;
}
this._progressAnchorStartX = this.progressAnchor.position.x;
}
private _resolveProgressAnchor(): void {
if (this.progressAnchor?.isValid) {
return;
}
this.progressAnchor = this.node
.getChildByName('Bg')
?.getChildByName('Title')
?.getChildByName('ProgressAnchor') ?? null;
}
private _applyAnimatedProgress(progress: number): void {
const clampedProgress = this._clampProgress(progress);
if (this.titleProgressBar?.isValid) {
this.titleProgressBar.progress = this._normalizeProgress(clampedProgress);
}
this._updateProgressAnchor(clampedProgress);
}
private _updateProgressAnchor(progress: number): void {
if (!this.progressAnchor?.isValid) {
return;
}
this._cacheProgressAnchorStartX();
const startX = this._progressAnchorStartX ?? this.progressAnchor.position.x;
const travelWidth = this._getProgressAnchorTravelWidth();
this.progressAnchor.setPosition(startX + travelWidth * progress, this.progressAnchor.position.y, this.progressAnchor.position.z);
const percentLabel = this.progressAnchor.getChildByName('Label')?.getComponent(Label);
if (percentLabel) {
percentLabel.string = `${Math.round(progress * 100)}%`;
}
}
private _getProgressAnchorTravelWidth(): number {
if (!this.titleProgressBar) {
return 0;
}
return Math.abs(this.titleProgressBar.totalLength * this.titleProgressBar.node.scale.x);
}
private _stopProgressAnimation(): void {
Tween.stopAllByTarget(this._progressTweenTarget);
}
@@ -372,6 +431,14 @@ export class PassModal extends BaseModal {
return Math.max(MIN_PROGRESS, Math.min(1, progress));
}
private _clampProgress(progress: number): number {
if (!Number.isFinite(progress) || progress <= 0) {
return 0;
}
return Math.min(1, progress);
}
/**
* 下一关按钮点击
*/