Files
18xchat/assets/Scripts/chat18x/ui/panels/ShowPanel.ts
T
2025-10-15 15:28:21 +08:00

198 lines
6.0 KiB
TypeScript

import {
_decorator,
Component,
Node,
Sprite,
UITransform,
VideoPlayer,
VideoClip,
view,
Size,
Vec3,
EventTouch,
} from "cc";
import li_BaseView from "db://assets/Scripts/Main/Common/li_BaseView";
import ResManager from "db://assets/Scripts/Main/Manager/ResManager";
import Utils from "db://assets/Scripts/Main/Common/Utils";
import { ViewManager } from "db://assets/Scripts/Main/Manager/ViewManager";
import { GButton } from "db://assets/Scripts/Main/Common/GButton";
import { SceneBgVideoLayer } from "../../../Sub/UI/SceneBgVideoLayer";
import { DataManager, DataId } from "../../data/DataManager";
import { EnvData } from "../../data/EnvData";
import { logger } from "db://assets/Scripts/Main/Common/Logger";
const { ccclass, property } = _decorator;
interface ShowPanelData {
url: string;
isImg: boolean;
closeFunc: Function;
}
@ccclass("ShowPanel")
export class ShowPanel extends li_BaseView {
@property(Sprite)
image: Sprite;
@property(Sprite)
splash: Sprite;
@property(UITransform)
videoArea: UITransform;
@property(VideoPlayer)
videoPlayer: VideoPlayer;
url: string;
func: Function;
isImg: boolean;
openUIDataCT(data: ShowPanelData) {
super.openUIDataCT(data);
this.url = data.url;
this.isImg = data.isImg;
this.func = data.closeFunc;
}
onLoadCT() {
this.show(this.url);
}
start() {
//this.splash.node.on(Node.EventType.TOUCH_START,this.onclickback);
GButton.BandClick(this.splash.node, this.onClose, this);
// 监听视频点击事件(Web平台上视频会覆盖UI,需要直接监听视频点击)
if (this.videoPlayer) {
this.videoPlayer.node.on(
VideoPlayer.EventType.CLICKED,
this.onClose,
this
);
}
// 阻止触摸事件传递,防止拖动画面(特别是Web平台视频超出屏幕时)
this.node.on(Node.EventType.TOUCH_START, this.onTouchBlock, this);
this.node.on(Node.EventType.TOUCH_MOVE, this.onTouchBlock, this);
this.node.on(Node.EventType.TOUCH_END, this.onTouchBlock, this);
this.node.on(Node.EventType.TOUCH_CANCEL, this.onTouchBlock, this);
}
onDestroy() {
// 清理视频点击事件监听
if (this.videoPlayer && this.videoPlayer.node) {
this.videoPlayer.node.off(
VideoPlayer.EventType.CLICKED,
this.onClose,
this
);
}
// 清理触摸事件监听
this.node.off(Node.EventType.TOUCH_START, this.onTouchBlock, this);
this.node.off(Node.EventType.TOUCH_MOVE, this.onTouchBlock, this);
this.node.off(Node.EventType.TOUCH_END, this.onTouchBlock, this);
this.node.off(Node.EventType.TOUCH_CANCEL, this.onTouchBlock, this);
}
/**
* 阻止触摸事件传递,防止拖动画面
*/
private onTouchBlock(event: EventTouch) {
// 阻止事件冒泡
event.propagationStopped = true;
// 阻止浏览器默认行为(如拖动、滚动)
event.preventDefault();
}
protected onClose() {
// 停止视频播放
if (this.videoPlayer) {
this.videoPlayer.stop();
}
if (this.func) {
this.func();
}
super.onClose();
}
show(path: string) {
const envData = DataManager.I.getDataById<EnvData>(DataId.Env);
if (this.isImg) {
// 加载远程资源
let newPath = envData.cdn + "/" + "Girls/" + path + ".png";
ResManager.I.changeRemoteSpriteFrame(this.image, newPath, () => {
// 固定高度为 1334,等比缩放宽度
const targetHeight = 1334;
const uiTransform = this.image.node.getComponent(UITransform);
if (uiTransform && uiTransform.height > 0) {
const scale = targetHeight / uiTransform.height;
uiTransform.height = targetHeight;
uiTransform.width = uiTransform.width * scale;
}
});
} else {
// 使用自己的 videoPlayer 进行置顶显示
if (this.videoPlayer) {
const targetSize = this.videoArea
? new Size(this.videoArea.width, this.videoArea.height)
: new Size(600, 800);
// 加载远程资源
let newPath = envData.cdn + "/" + "Girls/" + path + ".mp4";
ResManager.I.loadRemoteVideo(
this.videoPlayer,
newPath,
(res: VideoClip) => {
// 设置视频大小和位置
const uiTransform = this.videoPlayer.node.getComponent(UITransform);
if (uiTransform && this.videoArea) {
uiTransform.setContentSize(targetSize.width, targetSize.height);
// 设置位置为 videoArea 的位置
const pos = this.videoArea.node.getWorldPosition();
this.videoPlayer.node.setWorldPosition(pos);
}
this.videoPlayer.loop = true;
this.videoPlayer.play();
// 延迟调整缩放以填充区域
this.scheduleOnce(() => {
this.adjustVideoScale();
}, 0.1);
}
);
} else {
// 如果没有配置 videoPlayer,使用 SceneBgVideoLayer 作为后备
const targetSize = this.videoArea
? new Size(this.videoArea.width, this.videoArea.height)
: new Size(600, 800);
const videoAreaPos = this.videoArea
? this.videoArea.node.getWorldPosition()
: undefined;
if (SceneBgVideoLayer.handle) {
SceneBgVideoLayer.handle.playVideo(path, {
loop: true,
size: targetSize,
position: videoAreaPos,
});
}
}
}
}
/**
* 调整视频缩放以填满区域
*/
private adjustVideoScale() {
if (!this.videoPlayer || !this.videoArea) return;
const videoTransform = this.videoPlayer.node.getComponent(UITransform);
if (videoTransform && videoTransform.height > 0) {
const scaleX = this.videoArea.width / videoTransform.width;
const scaleY = this.videoArea.height / videoTransform.height;
const scale = Math.max(scaleX, scaleY); // 填满整个区域
this.videoPlayer.node.setScale(new Vec3(scale, scale, 1));
logger.log(`ShowPanel: 调整视频缩放到 ${scale}`);
}
}
}