perf: 优化通关弹窗进度条
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 下一关按钮点击
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user