|
1 |
| -import { Icon } from '@blueprintjs/core'; |
| 1 | +import { Button, Tooltip } from '@blueprintjs/core'; |
2 | 2 | import { IconNames } from '@blueprintjs/icons';
|
3 | 3 | import { useFullscreen } from '@mantine/hooks';
|
4 | 4 | import React from 'react';
|
@@ -95,51 +95,53 @@ function Game() {
|
95 | 95 |
|
96 | 96 | // Logic for the fullscreen button to dynamically adjust its size, position and padding
|
97 | 97 | // based on the size of the game display.
|
98 |
| - const [iconSize, setIconSize] = React.useState(0); |
99 | 98 | const [iconLeft, setIconLeft] = React.useState('0px');
|
100 | 99 | const [iconPadding, setIconPadding] = React.useState('0px');
|
101 | 100 |
|
102 |
| - React.useEffect(() => { |
103 |
| - const handleResize = () => { |
104 |
| - if (gameDisplayRef.current) { |
105 |
| - const aspectRatio = 16 / 9; |
106 |
| - const height = gameDisplayRef.current.offsetHeight; |
107 |
| - const width = gameDisplayRef.current.offsetWidth; |
108 |
| - const size = height / 40; |
109 |
| - const padding = height / 50; |
110 |
| - const leftOffset = |
111 |
| - isFullscreen || height * aspectRatio > width ? 0 : (width - height * aspectRatio) / 2; |
112 |
| - setIconSize(size); |
113 |
| - setIconPadding(`${padding}px`); |
114 |
| - setIconLeft(`${leftOffset}px`); |
115 |
| - } |
116 |
| - }; |
| 101 | + const handleResize = React.useCallback(() => { |
| 102 | + if (gameDisplayRef.current) { |
| 103 | + const aspectRatio = 16 / 9; |
| 104 | + const height = gameDisplayRef.current.offsetHeight; |
| 105 | + const width = gameDisplayRef.current.offsetWidth; |
| 106 | + const padding = height / 50; |
| 107 | + const leftOffset = |
| 108 | + isFullscreen || height * aspectRatio > width ? 0 : (width - height * aspectRatio) / 2; |
| 109 | + setIconPadding(`${padding}px`); |
| 110 | + setIconLeft(`${leftOffset}px`); |
| 111 | + } |
| 112 | + }, [isFullscreen]); |
117 | 113 |
|
118 |
| - // When exiting fullscreen, the browser might not have completed the transition |
119 |
| - // at the time handleResize is called, so the height of gameDisplayRef.current |
120 |
| - // is still the fullscreen height. |
121 |
| - // To fix this, we delay handleResize by 100ms. |
122 |
| - const delayedHandleResize = () => { |
123 |
| - setTimeout(handleResize, 100); |
124 |
| - }; |
| 114 | + // When exiting fullscreen, the browser might not have completed the transition |
| 115 | + // at the time handleResize is called, so the height of gameDisplayRef.current |
| 116 | + // is still the fullscreen height. |
| 117 | + // To fix this, we delay handleResize by 100ms. |
| 118 | + const delayedHandleResize = React.useCallback(() => { |
| 119 | + setTimeout(handleResize, 100); |
| 120 | + }, [handleResize]); |
125 | 121 |
|
| 122 | + React.useEffect(() => { |
126 | 123 | window.addEventListener('resize', delayedHandleResize);
|
127 | 124 | delayedHandleResize();
|
128 | 125 |
|
129 | 126 | return () => window.removeEventListener('resize', delayedHandleResize);
|
130 |
| - }, [isFullscreen]); |
| 127 | + }, [delayedHandleResize]); |
131 | 128 |
|
132 | 129 | return (
|
133 | 130 | <>
|
134 | 131 | <div id="game-display" ref={setGameDisplayRefs}>
|
135 |
| - <Icon |
136 |
| - id="fullscreen-button" |
137 |
| - icon={isFullscreen ? IconNames.MINIMIZE : IconNames.FULLSCREEN} |
138 |
| - color="white" |
139 |
| - htmlTitle={isFullscreen ? 'Exit full screen' : 'Full screen'} |
140 |
| - size={iconSize} |
141 |
| - onClick={enhancedToggleFullscreen} |
142 |
| - style={{ left: iconLeft, padding: iconPadding }} |
| 132 | + <Tooltip |
| 133 | + className="fullscreen-button" |
| 134 | + content={isFullscreen ? 'Exit fullscreen' : 'Fullscreen'} |
| 135 | + portalContainer={gameDisplayRef.current || undefined} |
| 136 | + renderTarget={({ isOpen, ...targetProps }) => ( |
| 137 | + <Button |
| 138 | + {...targetProps} |
| 139 | + minimal |
| 140 | + icon={isFullscreen ? IconNames.MINIMIZE : IconNames.MAXIMIZE} |
| 141 | + onClick={enhancedToggleFullscreen} |
| 142 | + style={{ left: iconLeft, padding: iconPadding }} |
| 143 | + /> |
| 144 | + )} |
143 | 145 | />
|
144 | 146 | </div>
|
145 | 147 | {isTestStudent && (
|
|
0 commit comments