I have a static web page, which works perfectly and maintains the 1:1 aspect ration of the checkerboard canvas element, when the browser window size changes:
Then I have prepared a simple ReactJS app, which tries to use the same code, but via useRef
.
It kind of works, but unfortunately there is this “stuck state”, where the canvas element size is not updated and it is too big.
Maybe the ResizeObserver
in my custom React component needs some extra notification, how to send it please?
Below is a copy of my custom src/components/PixiGame.jsx:
import { useEffect, useRef } from "react";
import { Link, useParams } from "react-router-dom";
import { Application, Graphics, Sprite, Texture } from "pixi.js-legacy";
import { useMediaQuery } from "@react-hook/media-query";
const PixiGame = () => {
const isSmallScreen = useMediaQuery("(max-width: 640px)");
const { pixiBunnies } = useParams();
const parentRef = useRef(null);
const childRef = useRef(null);
useEffect(() => {
const parentElement = parentRef.current;
const app = new Application({
backgroundColor: 0xccffcc,
width: 800,
height: 800,
});
// the PIXI app has created a canvas element - make it a child of the parent div
const childElement = app.view;
childElement.id = "child";
childElement.classList.add("child");
childRef.current = childElement;
parentElement.appendChild(childElement);
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
const { width, height } = entry.contentRect;
const minDimension = Math.floor(Math.min(width, height));
// maintain the 1:1 aspect ratio of the child element
childElement.style.width = `${minDimension}px`;
childElement.style.height = `${minDimension}px`;
}
});
resizeObserver.observe(parentElement);
// draw the checkerboard at the canvas
const background = new Graphics();
for (let i = 0; i < 8; i++) {
for (let j = 0; j < 8; j++) {
if ((i + j) % 2 == 0) {
background.beginFill(0xccccff);
background.drawRect(i * 100, j * 100, 100, 100);
background.endFill();
}
}
}
app.stage.addChild(background);
const texture = Texture.from("https://pixijs.com/assets/bunny.png");
const bunny = new Sprite(texture);
bunny.anchor.set(0.5);
bunny.x = 50;
bunny.y = 50;
bunny.width = 100;
bunny.height = 100;
app.stage.addChild(bunny);
return () => {
resizeObserver.unobserve(parentElement);
resizeObserver.disconnect();
app.destroy(true, true);
};
}, []);
return (
<div className="fullRoot">
<div className="hint">Game #{pixiBunnies} Score1:Score2</div>
<div className="parent" ref={parentRef}>{/* here a canvas is inserted */}</div>
<div className="status">A game hint to do this and that...</div>
{isSmallScreen && (
<div>
<Link to="/">Back to Games List</Link>
</div>
)}
</div>
);
};
export default PixiGame;