diff --git a/packages/webgal/src/UI/Menu/Options/Display/Display.tsx b/packages/webgal/src/UI/Menu/Options/Display/Display.tsx
index 41931d59f..b7bc13045 100644
--- a/packages/webgal/src/UI/Menu/Options/Display/Display.tsx
+++ b/packages/webgal/src/UI/Menu/Options/Display/Display.tsx
@@ -19,14 +19,14 @@ export function Display() {
{
- dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.yes }));
+ dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.on }));
setStorage();
},
() => {
- dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.no }));
+ dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.off }));
setStorage();
},
]}
diff --git a/packages/webgal/src/UI/Title/Title.tsx b/packages/webgal/src/UI/Title/Title.tsx
index 3365375a1..0bed4af1a 100644
--- a/packages/webgal/src/UI/Title/Title.tsx
+++ b/packages/webgal/src/UI/Title/Title.tsx
@@ -41,7 +41,7 @@ const Title: FC = () => {
onClick={() => {
playBgm(GUIState.titleBgm);
dispatch(setVisibility({ component: 'isEnterGame', visibility: true }));
- if (fullScreen === fullScreenOption.yes) document.documentElement.requestFullscreen();
+ if (fullScreen === fullScreenOption.on) document.documentElement.requestFullscreen();
}}
onMouseEnter={playSeEnter}
/>
diff --git a/packages/webgal/src/hooks/useFullScreen.ts b/packages/webgal/src/hooks/useFullScreen.ts
index c8e1d5431..bc7f6b699 100644
--- a/packages/webgal/src/hooks/useFullScreen.ts
+++ b/packages/webgal/src/hooks/useFullScreen.ts
@@ -1,23 +1,27 @@
+import { setStorage } from '@/Core/controller/storage/storageController';
import { RootState } from '@/store/store';
import { fullScreenOption } from '@/store/userDataInterface';
+import { setOptionData } from '@/store/userDataReducer';
import { useEffect } from 'react';
-import { useSelector } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
export function useFullScreen() {
const userDataState = useSelector((state: RootState) => state.userData);
const GUIState = useSelector((state: RootState) => state.GUI);
+ const dispatch = useDispatch();
const fullScreen = userDataState.optionData.fullScreen;
const isEnterGame = GUIState.isEnterGame;
+ let currentWindowHeight = window.innerHeight;
useEffect(() => {
switch (fullScreen) {
- case fullScreenOption.yes: {
+ case fullScreenOption.on: {
if (isEnterGame) {
document.documentElement.requestFullscreen();
};
break;
}
- case fullScreenOption.no: {
+ case fullScreenOption.off: {
if (document.fullscreenElement) {
document.exitFullscreen();
};
@@ -25,4 +29,21 @@ export function useFullScreen() {
}
}
}, [fullScreen]);
+
+ /**
+ * 通过窗口高度变化判断是否退出全屏,并更改全屏状态
+ */
+ useEffect(() => {
+ const isExitingFullScreen = () => {
+ if (fullScreen === fullScreenOption.on && isEnterGame && currentWindowHeight >= window.innerHeight) {
+ dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.off }));
+ setStorage();
+ }
+ currentWindowHeight = window.innerHeight;
+ };
+ window.addEventListener('resize', isExitingFullScreen);
+ return () => {
+ window.removeEventListener('resize', isExitingFullScreen);
+ };
+ }, [fullScreen, currentWindowHeight]);
};
diff --git a/packages/webgal/src/hooks/useHotkey.tsx b/packages/webgal/src/hooks/useHotkey.tsx
index d97601dfd..d39d21eea 100644
--- a/packages/webgal/src/hooks/useHotkey.tsx
+++ b/packages/webgal/src/hooks/useHotkey.tsx
@@ -1,16 +1,19 @@
import { useGenSyncRef } from '@/hooks/useGenSyncRef';
import { RootState } from '@/store/store';
import { useMounted, useUnMounted, useUpdated } from '@/hooks/useLifeCycle';
-import { useCallback, useRef } from 'react';
+import { useCallback, useEffect, useRef } from 'react';
import { componentsVisibility, MenuPanelTag } from '@/store/guiInterface';
import { setVisibility } from '@/store/GUIReducer';
-import { useDispatch } from 'react-redux';
+import { useDispatch, useSelector } from 'react-redux';
import { startFast, stopAll, stopFast } from '@/Core/controller/gamePlay/fastSkip';
import { nextSentence } from '@/Core/controller/gamePlay/nextSentence';
import styles from '@/UI/Backlog/backlog.module.scss';
import throttle from 'lodash/throttle';
import { fastSaveGame } from '@/Core/controller/storage/fastSaveLoad';
import { WebGAL } from '@/Core/WebGAL';
+import { setOptionData } from '@/store/userDataReducer';
+import { setStorage } from '@/Core/controller/storage/storageController';
+import { fullScreenOption } from '@/store/userDataInterface';
// options备用
export interface HotKeyType {
@@ -36,6 +39,7 @@ export function useHotkey(opt?: HotKeyType) {
usePanic();
useFastSaveBeforeUnloadPage();
useSpaceAndEnter();
+ useToggleFullScreen();
}
/**
@@ -364,3 +368,30 @@ function hasScrollToBottom(dom: Element) {
const { scrollTop, clientHeight, scrollHeight } = dom;
return scrollTop === 0;
}
+
+/**
+ * F11 进入全屏
+ */
+function useToggleFullScreen() {
+ const userDataState = useSelector((state: RootState) => state.userData);
+ const dispatch = useDispatch();
+ const fullScreen = userDataState.optionData.fullScreen;
+ useEffect(() => {
+ const handleKeyDown = (e: KeyboardEvent) => {
+ if (e.code === 'F11') {
+ e.preventDefault();
+ if (fullScreen !== fullScreenOption.on) {
+ dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.on }));
+ setStorage();
+ } else {
+ dispatch(setOptionData({ key: 'fullScreen', value: fullScreenOption.off }));
+ setStorage();
+ }
+ }
+ };
+ document.addEventListener('keydown', handleKeyDown);
+ return () => {
+ document.removeEventListener('keydown', handleKeyDown);
+ };
+ }, [fullScreen]);
+}
diff --git a/packages/webgal/src/store/userDataInterface.ts b/packages/webgal/src/store/userDataInterface.ts
index 374f2bf31..57f9a5f43 100644
--- a/packages/webgal/src/store/userDataInterface.ts
+++ b/packages/webgal/src/store/userDataInterface.ts
@@ -30,8 +30,8 @@ export enum voiceOption {
}
export enum fullScreenOption {
- yes,
- no,
+ on,
+ off,
}
/**
diff --git a/packages/webgal/src/store/userDataReducer.ts b/packages/webgal/src/store/userDataReducer.ts
index 755563932..a910dcc76 100644
--- a/packages/webgal/src/store/userDataReducer.ts
+++ b/packages/webgal/src/store/userDataReducer.ts
@@ -35,7 +35,7 @@ const initialOptionSet: IOptionData = {
textboxOpacity: 75,
language: language.zhCn,
voiceInterruption: voiceOption.yes,
- fullScreen: fullScreenOption.no,
+ fullScreen: fullScreenOption.off,
};
// 初始化用户数据
diff --git a/packages/webgal/src/translations/en.ts b/packages/webgal/src/translations/en.ts
index b72425e24..466a8e6df 100644
--- a/packages/webgal/src/translations/en.ts
+++ b/packages/webgal/src/translations/en.ts
@@ -64,10 +64,10 @@ const en = {
title: 'Display',
options: {
fullScreen: {
- title: 'Auto Full Screen',
+ title: 'Full Screen',
options: {
- yes: 'YES',
- no: 'NO',
+ on: 'ON',
+ off: 'OFF',
},
},
textSpeed: {
diff --git a/packages/webgal/src/translations/zh-cn.ts b/packages/webgal/src/translations/zh-cn.ts
index 3bbcac6ac..471b2a547 100644
--- a/packages/webgal/src/translations/zh-cn.ts
+++ b/packages/webgal/src/translations/zh-cn.ts
@@ -64,10 +64,10 @@ const zhCn = {
title: '显示',
options: {
fullScreen: {
- title: '自动全屏',
+ title: '全屏模式',
options: {
- yes: '是',
- no: '否',
+ on: '开启',
+ off: '关闭',
},
},
textSpeed: {