头像入版 页面跳转优化

This commit is contained in:
2025-09-11 17:07:29 +08:00
parent d6a9898c8d
commit 6bf85c6ad8
74 changed files with 4238 additions and 1070 deletions
@@ -2,6 +2,25 @@ import { ViewManager } from "db://assets/Scripts/Main/Manager/ViewManager";
import { UITransitionHelper } from "../utils/UITransitionHelper";
import GameRootUI from "../../Main/Common/GameRootUI";
/**
* 页面过渡动画类型枚举
*/
export enum PageTransitionType {
NONE = "none",
SLIDE_LEFT = "slide_left",
SLIDE_RIGHT = "slide_right",
}
/**
* 页面过渡动画配置接口
*/
export interface PageTransitionConfig {
incomingTransition: PageTransitionType;
outgoingTransition: PageTransitionType;
duration?: number;
simultaneous?: boolean;
}
/**
* 导航管理器
*
@@ -28,6 +47,183 @@ export class NavigationManager {
private constructor() {}
/**
* 通用页面导航方法,支持过渡动画
*
* @param {string} targetPanel - 目标面板名称
* @param {any} navigationData - 导航数据
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
* @param {any} currentPanel - 当前面板实例(可选)
* @param {Function} onComplete - 完成回调(可选)
*
* @example
* ```typescript
* NavigationManager.Instance.navigateWithTransition(
* "ChatPanel",
* { roleId: 10001 },
* { incomingTransition: PageTransitionType.SLIDE_RIGHT, outgoingTransition: PageTransitionType.SLIDE_LEFT },
* currentPanel
* );
* ```
*/
public navigateWithTransition(
targetPanel: string,
navigationData: any,
transitionConfig: PageTransitionConfig,
currentPanel?: any,
onComplete?: Function
): void {
if (!targetPanel) {
console.warn("NavigationManager: Target panel name is required");
return;
}
console.log(
`Navigating to ${targetPanel} with transition:`,
transitionConfig
);
//const correntPos = currentPanel.node.position;
const duration = transitionConfig.duration || 0.1;
const useTransition =
transitionConfig.incomingTransition !== PageTransitionType.NONE ||
transitionConfig.outgoingTransition !== PageTransitionType.NONE;
if (!useTransition) {
ViewManager.I.openBundlesView(targetPanel, navigationData, onComplete);
if (
currentPanel &&
currentPanel.onClose &&
typeof currentPanel.onClose === "function"
) {
currentPanel.onClose();
//currentPanel.node.position = correntPos;
}
return;
}
const extendedNavigationData = {
...navigationData,
withTransition: true,
transitionType: transitionConfig.incomingTransition,
};
ViewManager.I.openBundlesView(
targetPanel,
extendedNavigationData,
(targetNode) => {
this._executeTransition(
targetNode,
currentPanel,
transitionConfig,
duration,
onComplete
);
}
);
}
/**
* 执行页面过渡动画的私有方法
*
* @private
* @param {any} targetNode - 目标节点
* @param {any} currentPanel - 当前面板
* @param {PageTransitionConfig} config - 动画配置
* @param {number} duration - 动画时长
* @param {Function} onComplete - 完成回调
*/
private _executeTransition(
targetNode: any,
currentPanel: any,
config: PageTransitionConfig,
duration: number,
onComplete?: Function
): void {
const executeIncomingAnimation = (callback?: Function) => {
if (
config.incomingTransition === PageTransitionType.NONE ||
!targetNode
) {
callback && callback();
return;
}
switch (config.incomingTransition) {
case PageTransitionType.SLIDE_RIGHT:
UITransitionHelper.slideInFromRight(targetNode, duration, callback);
break;
case PageTransitionType.SLIDE_LEFT:
UITransitionHelper.slideInFromLeft(targetNode, duration, callback);
break;
default:
callback && callback();
break;
}
};
const executeOutgoingAnimation = (callback?: Function) => {
if (
config.outgoingTransition === PageTransitionType.NONE ||
!currentPanel ||
!currentPanel.node ||
!currentPanel.node.isValid
) {
callback && callback();
return;
}
switch (config.outgoingTransition) {
case PageTransitionType.SLIDE_LEFT:
UITransitionHelper.slideOutToLeft(
currentPanel.node,
duration,
callback
);
break;
case PageTransitionType.SLIDE_RIGHT:
UITransitionHelper.slideOutToRight(
currentPanel.node,
duration,
callback
);
break;
default:
callback && callback();
break;
}
};
const closeCurrentPanel = () => {
if (
currentPanel &&
currentPanel.onClose &&
typeof currentPanel.onClose === "function"
) {
if (currentPanel.node.name !== "ThemePanel") currentPanel.onClose();
}
onComplete && onComplete();
};
if (config.simultaneous) {
let completedAnimations = 0;
const animationComplete = () => {
completedAnimations++;
if (completedAnimations >= 2) {
closeCurrentPanel();
}
};
executeIncomingAnimation(animationComplete);
executeOutgoingAnimation(animationComplete);
} else {
executeOutgoingAnimation(() => {
executeIncomingAnimation(closeCurrentPanel);
});
}
}
/**
* 进入角色列表页面
*
@@ -38,15 +234,56 @@ export class NavigationManager {
* NavigationManager.Instance.navigateToGirlList(1);
* ```
*/
public navigateToGirlList(themeId: number): void {
public navigateToGirlList(themeId: number): void;
/**
* 进入角色列表页面(带过渡动画)
*
* @param {number} themeId - 主题ID,用于筛选角色
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
* @param {any} currentPanel - 当前面板实例(可选)
*
* @example
* ```typescript
* NavigationManager.Instance.navigateToGirlList(1,
* { incomingTransition: PageTransitionType.SLIDE_RIGHT, outgoingTransition: PageTransitionType.FADE },
* this
* );
* ```
*/
public navigateToGirlList(
themeId: number,
transitionConfig?: PageTransitionConfig,
currentPanel?: any
): void;
public navigateToGirlList(
themeId: number,
transitionConfig?: PageTransitionConfig,
currentPanel?: any
): void {
if (themeId == null || themeId < 0) {
console.warn("Invalid theme ID for girl list navigation:", themeId);
return;
}
GameRootUI.I.hideDefaultView();
console.log(`Navigating to girl list with theme ID: ${themeId}`);
ViewManager.I.openBundlesView("GirlListPanel", themeId);
if (transitionConfig) {
const navigationData = {
category: themeId,
withTransition: true,
};
this.navigateWithTransition(
"GirlListPanel",
navigationData,
transitionConfig,
currentPanel,
() => {
GameRootUI.I.hideDefaultView();
}
);
} else {
ViewManager.I.openBundlesView("GirlListPanel", themeId);
}
}
/**
@@ -59,26 +296,62 @@ export class NavigationManager {
* NavigationManager.Instance.navigateToChat(10001);
* ```
*/
public navigateToChat(roleId: number): void {
public navigateToChat(roleId: number): void;
/**
* 进入聊天页面(带过渡动画)
*
* @param {number} roleId - 角色ID
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
* @param {any} currentPanel - 当前面板实例(可选)
*
* @example
* ```typescript
* NavigationManager.Instance.navigateToChat(10001,
* { incomingTransition: PageTransitionType.FADE, outgoingTransition: PageTransitionType.SLIDE_LEFT },
* this
* );
* ```
*/
public navigateToChat(
roleId: number,
transitionConfig?: PageTransitionConfig,
currentPanel?: any
): void;
public navigateToChat(
roleId: number,
transitionConfig?: PageTransitionConfig,
currentPanel?: any
): void {
if (roleId == null || roleId <= 0) {
console.warn("Invalid role ID for chat navigation:", roleId);
return;
}
GameRootUI.I.hideDefaultView();
console.log(`Navigating to chat with role ID: ${roleId}`);
ViewManager.I.openBundlesView("ChatPanel", roleId);
if (transitionConfig) {
this.navigateWithTransition(
"ChatPanel",
roleId,
transitionConfig,
currentPanel
);
} else {
ViewManager.I.openBundlesView("ChatPanel", roleId);
}
}
/**
* 带过渡动画进入聊天页面
* 从GirlDetailPanel平滑过渡到ChatPanel
*
* @param {string} categoryId - 类别ID
* @param {number} roleId - 角色ID
* @param {any} currentPanel - 当前面板实例(GirlDetailPanel
*
* @example
* ```typescript
* NavigationManager.Instance.navigateToChatWithTransition(10001, this);
* NavigationManager.Instance.navigateToChatWithTransition("1", 10001, this);
* ```
*/
public navigateToChatWithTransition(
@@ -94,30 +367,24 @@ export class NavigationManager {
return;
}
console.log(`Navigating to chat with transition, role ID: ${roleId}`);
const navigationData = {
categoryId: categoryId,
roleId: roleId,
withSlideTransition: true,
};
// 打开ChatPanel,同时标记需要执行滑入动画
ViewManager.I.openBundlesView(
const transitionConfig: PageTransitionConfig = {
incomingTransition: PageTransitionType.SLIDE_RIGHT,
outgoingTransition: PageTransitionType.SLIDE_LEFT,
duration: 0.3,
simultaneous: true,
};
this.navigateWithTransition(
"ChatPanel",
{
categoryId: categoryId,
roleId: roleId,
withSlideTransition: true,
},
(chatNode) => {
// ChatPanel打开后,如果有当前面板,执行滑出动画
if (currentPanel && currentPanel.node && currentPanel.node.isValid) {
UITransitionHelper.slideOutToLeft(currentPanel.node, 0.3, () => {
// 滑出动画完成后关闭原面板
if (
currentPanel.onClose &&
typeof currentPanel.onClose === "function"
) {
currentPanel.onClose();
}
});
}
}
navigationData,
transitionConfig,
currentPanel
);
}
@@ -131,14 +398,49 @@ export class NavigationManager {
* NavigationManager.Instance.navigateToGirlDetail(10001);
* ```
*/
public navigateToGirlDetail(roleId: number): void {
public navigateToGirlDetail(roleId: number): void;
/**
* 进入角色详情页面(带过渡动画)
*
* @param {number} roleId - 角色ID
* @param {PageTransitionConfig} transitionConfig - 过渡动画配置
* @param {any} currentPanel - 当前面板实例(可选)
*
* @example
* ```typescript
* NavigationManager.Instance.navigateToGirlDetail(10001,
* { incomingTransition: PageTransitionType.SLIDE_RIGHT, outgoingTransition: PageTransitionType.SLIDE_LEFT },
* this
* );
* ```
*/
public navigateToGirlDetail(
roleId: number,
transitionConfig?: PageTransitionConfig,
currentPanel?: any
): void;
public navigateToGirlDetail(
roleId: number,
transitionConfig?: PageTransitionConfig,
currentPanel?: any
): void {
if (roleId == null || roleId <= 0) {
console.warn("Invalid role ID for detail navigation:", roleId);
return;
}
console.log(`Navigating to girl detail with role ID: ${roleId}`);
ViewManager.I.openBundlesView("GirlDetailPanel", roleId);
if (transitionConfig) {
this.navigateWithTransition(
"GirlDetailPanel",
roleId,
transitionConfig,
currentPanel
);
} else {
ViewManager.I.openBundlesView("GirlDetailPanel", roleId);
}
}
/**
@@ -184,4 +486,39 @@ export class NavigationManager {
// TODO: 实现返回上一页功能
console.log("Go back feature not implemented yet");
}
/**
* 获取预设的过渡动画配置
*/
public static getTransitionPresets() {
return {
SLIDE_LEFT_TO_RIGHT: {
incomingTransition: PageTransitionType.SLIDE_RIGHT,
outgoingTransition: PageTransitionType.SLIDE_LEFT,
duration: 0.1,
simultaneous: true,
} as PageTransitionConfig,
SLIDE_RIGHT_TO_LEFT: {
incomingTransition: PageTransitionType.SLIDE_LEFT,
outgoingTransition: PageTransitionType.SLIDE_RIGHT,
duration: 0.1,
simultaneous: true,
} as PageTransitionConfig,
SLIDE_OVER: {
incomingTransition: PageTransitionType.SLIDE_RIGHT,
outgoingTransition: PageTransitionType.NONE,
duration: 0.1,
simultaneous: true,
} as PageTransitionConfig,
SLIDE_UNDER: {
incomingTransition: PageTransitionType.NONE,
outgoingTransition: PageTransitionType.SLIDE_LEFT,
duration: 0.1,
simultaneous: true,
} as PageTransitionConfig,
};
}
}