-
Notifications
You must be signed in to change notification settings - Fork 172
Add a fullscreen button for the game div container #2855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
177c86b
2031975
0832d8b
af140dc
d9e3a2e
31fc2c9
1a5b3a9
eef4ae8
f9e4c3e
5ffcabe
7ec8ad3
76e09cb
744b8b3
3c1a46d
4b50bab
daac858
e41fd96
a0d28d1
4f4718e
e2b6672
9c6b6bf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
import { Icon } from '@blueprintjs/core'; | ||
import React from 'react'; | ||
import { useDispatch } from 'react-redux'; | ||
import { useTypedSelector } from 'src/commons/utils/Hooks'; | ||
|
@@ -50,9 +51,82 @@ function Game() { | |
} | ||
}, [session, achievements, goals]); | ||
|
||
// Logic for the fullscreen button to toggle fullscreen. | ||
// Entering fullscreen will also lock the screen orientation to landscape. | ||
const [isFullScreen, setIsFullScreen] = React.useState(false); | ||
const toggleFullScreen = () => { | ||
const elem = document.getElementById('game-display') as HTMLElement; | ||
|
||
if (!isFullScreen) { | ||
if (elem.requestFullscreen) { | ||
sayomaki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
elem.requestFullscreen().then(() => { | ||
if (window.screen.orientation) { | ||
window.screen.orientation.lock('landscape'); | ||
} | ||
}); | ||
} | ||
} else { | ||
if (document.exitFullscreen) { | ||
sayomaki marked this conversation as resolved.
Show resolved
Hide resolved
|
||
document.exitFullscreen().then(() => { | ||
if (window.screen.orientation) { | ||
window.screen.orientation.unlock(); | ||
} | ||
}); | ||
} | ||
} | ||
setIsFullScreen(!isFullScreen); | ||
}; | ||
|
||
// Logic for the fullscreen button to dynamically adjust its size, position and padding | ||
// based on the size of the game display. | ||
const [iconSize, setIconSize] = React.useState(0); | ||
const [iconLeft, setIconLeft] = React.useState('0px'); | ||
const [iconPadding, setIconPadding] = React.useState('0px'); | ||
const gameDisplayRef = React.useRef<HTMLDivElement | null>(null); | ||
|
||
React.useEffect(() => { | ||
const handleResize = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please don't put this function definition inside the |
||
if (gameDisplayRef.current) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are the values never reset otherwise? |
||
const aspectRatio = 16 / 9; | ||
const height = gameDisplayRef.current.offsetHeight; | ||
const width = gameDisplayRef.current.offsetWidth; | ||
const size = height / 40; | ||
const padding = height / 50; | ||
const leftOffset = | ||
isFullScreen || height * aspectRatio > width ? 0 : (width - height * aspectRatio) / 2; | ||
setIconSize(size); | ||
setIconPadding(`${padding}px`); | ||
setIconLeft(`${leftOffset}px`); | ||
} | ||
}; | ||
|
||
// When exiting fullscreen, the browser might not have completed the transition | ||
// at the time handleResize is called, so the height of gameDisplayRef.current | ||
// is still the fullscreen height. | ||
// To fix this, we delay handleResize by 100ms. | ||
const delayedHandleResize = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ditto on moving this out of the |
||
setTimeout(handleResize, 100); | ||
}; | ||
|
||
window.addEventListener('resize', delayedHandleResize); | ||
delayedHandleResize(); | ||
|
||
return () => window.removeEventListener('resize', delayedHandleResize); | ||
Comment on lines
+124
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is the resize observer for when we already have |
||
}, [isFullScreen]); | ||
|
||
return ( | ||
<> | ||
<div id="game-display"></div> | ||
<div id="game-display" ref={gameDisplayRef}> | ||
<Icon | ||
id="fullscreen-button" | ||
icon={isFullScreen ? 'minimize' : 'fullscreen'} | ||
color="white" | ||
htmlTitle={isFullScreen ? 'Exit full screen' : 'Full screen'} | ||
size={iconSize} | ||
onClick={toggleFullScreen} | ||
style={{ left: iconLeft, padding: iconPadding }} | ||
/> | ||
</div> | ||
{isTestStudent && ( | ||
<div className="Horizontal"> | ||
<button | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,3 +4,9 @@ | |
width: 100%; | ||
align-items: center; | ||
} | ||
|
||
#fullscreen-button { | ||
position: absolute; | ||
cursor: pointer; | ||
z-index: 100; | ||
} |
Uh oh!
There was an error while loading. Please reload this page.