迁移赛马悬浮按钮脚本
This commit is contained in:
@@ -29,6 +29,7 @@
|
||||
* - game-hall.js:处理娱乐大厅弹窗和游戏入口卡片。
|
||||
* - game-bootstrap.js:提供非关键游戏延迟初始化工具。
|
||||
* - game-panels.js:处理通用游戏面板关闭事件。
|
||||
* - horse-race-fab.js:处理赛马竞猜悬浮按钮拖动与打开面板。
|
||||
* - holiday-modal.js:处理节日福利弹窗、广播监听、领取状态和系统消息入口。
|
||||
* - initial-state.js:恢复首屏历史消息、欢迎消息、入场特效和挂起婚姻事件。
|
||||
* - bank-modal.js:处理银行弹窗、转账、排行和标签切换。
|
||||
@@ -106,6 +107,7 @@ export {
|
||||
export { bindGameHallControls, closeGameHall, openGameHall } from "./chat-room/game-hall.js";
|
||||
export { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/game-bootstrap.js";
|
||||
export { bindGamePanelControls } from "./chat-room/game-panels.js";
|
||||
export { bindHorseRaceFabControls, horseRaceFab } from "./chat-room/horse-race-fab.js";
|
||||
export {
|
||||
bindHolidayModalControls,
|
||||
buildHolidayClaimActionButton,
|
||||
@@ -250,6 +252,7 @@ import {
|
||||
import { bindGameHallControls, closeGameHall, openGameHall } from "./chat-room/game-hall.js";
|
||||
import { bindGameBootstrapControls, deferChatGameBootstrap } from "./chat-room/game-bootstrap.js";
|
||||
import { bindGamePanelControls } from "./chat-room/game-panels.js";
|
||||
import { bindHorseRaceFabControls, horseRaceFab } from "./chat-room/horse-race-fab.js";
|
||||
import {
|
||||
bindHolidayModalControls,
|
||||
buildHolidayClaimActionButton,
|
||||
@@ -401,6 +404,8 @@ if (typeof window !== "undefined") {
|
||||
bindGameBootstrapControls,
|
||||
deferChatGameBootstrap,
|
||||
bindGamePanelControls,
|
||||
bindHorseRaceFabControls,
|
||||
horseRaceFab,
|
||||
bindHolidayModalControls,
|
||||
buildHolidayClaimActionButton,
|
||||
buildHolidaySystemMessage,
|
||||
@@ -559,6 +564,7 @@ if (typeof window !== "undefined") {
|
||||
window.deferChatGameBootstrap = deferChatGameBootstrap;
|
||||
window.lotteryPanel = lotteryPanel;
|
||||
window.openGameHall = openGameHall;
|
||||
window.horseRaceFab = horseRaceFab;
|
||||
window.openLotteryPanel = openLotteryPanel;
|
||||
window.openBankModal = openBankModal;
|
||||
window.showLotteryMsg = showLotteryMsg;
|
||||
@@ -638,6 +644,7 @@ if (typeof window !== "undefined") {
|
||||
bindGameHallControls();
|
||||
bindGameBootstrapControls();
|
||||
bindGamePanelControls();
|
||||
bindHorseRaceFabControls();
|
||||
bindHolidayModalControls();
|
||||
bindChatInitialStateControls();
|
||||
bindBankControls();
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
// 赛马竞猜悬浮按钮组件,负责拖动位置持久化和打开赛马面板。
|
||||
|
||||
const HORSE_RACE_FAB_STORAGE_KEY = "horse_race_fab_pos";
|
||||
|
||||
/**
|
||||
* 安全读取赛马悬浮按钮保存的位置。
|
||||
*
|
||||
* @returns {{x?: number, y?: number}|null}
|
||||
*/
|
||||
function readSavedHorseRaceFabPosition() {
|
||||
try {
|
||||
return JSON.parse(localStorage.getItem(HORSE_RACE_FAB_STORAGE_KEY) || "null");
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建赛马竞猜悬浮按钮 Alpine 组件。
|
||||
*
|
||||
* @returns {Record<string, any>}
|
||||
*/
|
||||
export function horseRaceFab() {
|
||||
const saved = readSavedHorseRaceFabPosition();
|
||||
|
||||
return {
|
||||
visible: false,
|
||||
posX: saved?.x ?? 80,
|
||||
posY: saved?.y ?? 90,
|
||||
dragging: false,
|
||||
_startX: 0,
|
||||
_startY: 0,
|
||||
_origX: 0,
|
||||
_origY: 0,
|
||||
_moved: false,
|
||||
|
||||
/**
|
||||
* 开始拖动赛马悬浮按钮。
|
||||
*
|
||||
* @param {PointerEvent} event 指针事件
|
||||
* @returns {void}
|
||||
*/
|
||||
startDrag(event) {
|
||||
this.dragging = true;
|
||||
this._moved = false;
|
||||
this._startX = event.clientX;
|
||||
this._startY = event.clientY;
|
||||
this._origX = this.posX;
|
||||
this._origY = this.posY;
|
||||
event.currentTarget.setPointerCapture?.(event.pointerId);
|
||||
},
|
||||
|
||||
/**
|
||||
* 拖动过程中约束按钮不超出视口。
|
||||
*
|
||||
* @param {PointerEvent} event 指针事件
|
||||
* @returns {void}
|
||||
*/
|
||||
onDrag(event) {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dx = event.clientX - this._startX;
|
||||
const dy = event.clientY - this._startY;
|
||||
|
||||
if (Math.abs(dx) > 3 || Math.abs(dy) > 3) {
|
||||
this._moved = true;
|
||||
}
|
||||
|
||||
// 赛马按钮使用 right/bottom 定位,拖动方向需要反向换算。
|
||||
this.posX = Math.max(4, Math.min(window.innerWidth - 132, this._origX - dx));
|
||||
this.posY = Math.max(4, Math.min(window.innerHeight - 132, this._origY - dy));
|
||||
},
|
||||
|
||||
/**
|
||||
* 结束拖动;没有移动时按点击处理并打开赛马面板。
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
endDrag() {
|
||||
if (!this.dragging) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.dragging = false;
|
||||
localStorage.setItem(HORSE_RACE_FAB_STORAGE_KEY, JSON.stringify({
|
||||
x: this.posX,
|
||||
y: this.posY,
|
||||
}));
|
||||
|
||||
if (!this._moved) {
|
||||
this.openPanel();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* 打开赛马主面板。
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
openPanel() {
|
||||
const panel = document.getElementById("horse-race-panel");
|
||||
|
||||
if (!panel || typeof window.Alpine?.$data !== "function") {
|
||||
return;
|
||||
}
|
||||
|
||||
window.Alpine.$data(panel).openFromHall();
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 挂载赛马悬浮按钮全局组件名,兼容 Blade 的 x-data。
|
||||
*
|
||||
* @returns {void}
|
||||
*/
|
||||
export function bindHorseRaceFabControls() {
|
||||
if (typeof window === "undefined") {
|
||||
return;
|
||||
}
|
||||
|
||||
window.horseRaceFab = horseRaceFab;
|
||||
}
|
||||
@@ -328,59 +328,7 @@
|
||||
</style>
|
||||
|
||||
<script>
|
||||
/**
|
||||
* 赛马竞猜悬浮按钮 Alpine 组件(拖动 + localStorage 位置持久化)
|
||||
*/
|
||||
function horseRaceFab() {
|
||||
const STORAGE_KEY = 'horse_race_fab_pos';
|
||||
const saved = JSON.parse(localStorage.getItem(STORAGE_KEY) || 'null');
|
||||
return {
|
||||
visible: false,
|
||||
posX: saved?.x ?? 80,
|
||||
posY: saved?.y ?? 90,
|
||||
dragging: false,
|
||||
_startX: 0,
|
||||
_startY: 0,
|
||||
_origX: 0,
|
||||
_origY: 0,
|
||||
_moved: false,
|
||||
|
||||
startDrag(e) {
|
||||
this.dragging = true;
|
||||
this._moved = false;
|
||||
this._startX = e.clientX;
|
||||
this._startY = e.clientY;
|
||||
this._origX = this.posX;
|
||||
this._origY = this.posY;
|
||||
e.currentTarget.setPointerCapture?.(e.pointerId);
|
||||
},
|
||||
|
||||
onDrag(e) {
|
||||
if (!this.dragging) return;
|
||||
const dx = e.clientX - this._startX;
|
||||
const dy = e.clientY - this._startY;
|
||||
if (Math.abs(dx) > 3 || Math.abs(dy) > 3) this._moved = true;
|
||||
// right 定位:往右拖 dx>0 → right 减小;bottom 定位:往下拖 dy>0 → bottom 减小
|
||||
this.posX = Math.max(4, Math.min(window.innerWidth - 132, this._origX - dx));
|
||||
this.posY = Math.max(4, Math.min(window.innerHeight - 132, this._origY - dy));
|
||||
},
|
||||
|
||||
endDrag(e) {
|
||||
if (!this.dragging) return;
|
||||
this.dragging = false;
|
||||
localStorage.setItem(STORAGE_KEY, JSON.stringify({
|
||||
x: this.posX,
|
||||
y: this.posY
|
||||
}));
|
||||
if (!this._moved) this.openPanel();
|
||||
},
|
||||
|
||||
openPanel() {
|
||||
const panel = document.getElementById('horse-race-panel');
|
||||
if (panel) Alpine.$data(panel).openFromHall();
|
||||
},
|
||||
};
|
||||
}
|
||||
{{-- 赛马竞猜悬浮按钮脚本已迁移到 resources/js/chat-room/horse-race-fab.js --}}
|
||||
|
||||
/**
|
||||
* 赛马竞猜主面板 Alpine 组件
|
||||
|
||||
Reference in New Issue
Block a user