Reputation: 793
I'm currently working on a pet web project with react and I'm using a container that's 16:9 and scaling with the current viewport. The idea is based on a pen, I've created with vanilla JS (https://codepen.io/AllBitsEqual/pen/PgMrgm) and that's already working like a charm.
function adjustScreen() {...}
adjustScreen()
[...]
const resizeHandler = function () { adjustScreen() }
window.addEventListener('resize', helpers.debounce(resizeHandler, 250, this))
I've now written a script that's sitting in my App.jsx, (un)binds itself via useEffect and calculates the current size of the viewport to adjust the container, whenever the viewport changes (throttled for performance). I'm also using media queries to adjust the size and font size of elements in the container, which is working ok but isn't much fun to work with.
I want to expand on this idea and change the font size of the HTML Element in the same function that calculated the current container size so that I can use REM to scale font-size and other elements based on my calculated root font size.
Is there a valid and future-proofed way of changing the font-size style of my Tag via ReactJS either via the style tag or style attribute?
Upvotes: 1
Views: 2865
Reputation: 793
For now I've resorted to using "document.documentElement" and "style.fontSize" to achieve what I wanted but I'm not 100% sure this is the best solution. I'll see if I can find or get a better solution before I accept my own answer as the best...
I'm using useState for the game dimensions and within the useEffect, I'm attaching the listener to resize events, which I throttle a bit for performance reasons.
const App = () => {
const game_outerDOMNode = useRef(null)
const rootElement = document.documentElement
function getWindowDimensions() {
const { innerWidth: width, innerHeight: height } = window
return {
width,
height,
}
}
const [gameDimensions, setGameDimensions] = useState({ width: 0, height: 0})
useEffect(() => {
function adjustScreen() {
const game_outer = game_outerDOMNode.current
const ratioHeight = 1 / 1.78
const ratioWidth = 1.78
const { width: vw, height: vh } = getWindowDimensions()
const width = (vw > vh)
? (vh * ratioWidth <= vw)
? (vh * ratioWidth)
: (vw)
: (vh * ratioHeight <= vw)
? (vh * ratioHeight)
: (vw)
const height = (vw > vh)
? (vw * ratioHeight <= vh)
? (vw * ratioHeight)
: (vh)
: (vw * ratioWidth <= vh)
? (vw * ratioWidth)
: (vh)
const longestSide = height > width ? height : width
const fontSize = longestSide/37.5 // my calculated global base size
setGameDimensions({ width, height })
rootElement.style.fontSize = `${fontSize}px`
}
const debouncedResizeHandler = debounce(200, () => {
adjustScreen()
})
adjustScreen()
window.addEventListener('resize', debouncedResizeHandler)
return () => window.removeEventListener('resize', debouncedResizeHandler)
}, [rootElement.style.fontSize])
const { width: gameWidth, height: gameHeight } = gameDimensions
return (
<div
className="game__outer"
ref={game_outerDOMNode}
style={{ width: gameWidth, height: gameHeight }}
>
<div className="game__inner">
{my actual game code}
</div>
</div>
)
}
Upvotes: 1