@pixi/react
Version:
Write PixiJS applications using React declarative style.
130 lines (127 loc) • 3.94 kB
JavaScript
import { jsx } from 'react/jsx-runtime';
import { useContextBridge, FiberProvider } from 'its-fine';
import { TextStyle, extensions } from 'pixi.js';
import { forwardRef, useRef, useImperativeHandle, useCallback, useEffect } from 'react';
import { createRoot } from '../core/createRoot.mjs';
import { roots } from '../core/roots.mjs';
import { processUnmountQueue } from '../helpers/processUnmountQueue.mjs';
import { queueForUnmount } from '../helpers/queueForUnmount.mjs';
import { unqueueForUnmount } from '../helpers/unqueueForUnmount.mjs';
import { useIsomorphicLayoutEffect } from '../hooks/useIsomorphicLayoutEffect.mjs';
;
const originalDefaultTextStyle = { ...TextStyle.defaultTextStyle };
const ApplicationImplementation = forwardRef(function Application2(props, forwardedRef) {
const {
children,
className,
defaultTextStyle,
extensions: extensions$1,
onInit,
resizeTo,
...applicationProps
} = props;
const Bridge = useContextBridge();
const applicationRef = useRef(null);
const canvasRef = useRef(null);
const extensionsRef = useRef(/* @__PURE__ */ new Set());
useImperativeHandle(forwardedRef, () => ({
getApplication() {
return applicationRef.current;
},
getCanvas() {
return canvasRef.current;
}
}));
const updateResizeTo = useCallback(() => {
const application = applicationRef.current;
if (application) {
if (resizeTo) {
if ("current" in resizeTo) {
if (resizeTo.current instanceof HTMLElement) {
application.resizeTo = resizeTo.current;
}
} else {
application.resizeTo = resizeTo;
}
} else {
application.resizeTo = void 0;
}
}
}, [resizeTo]);
const handleInit = useCallback((application) => {
processUnmountQueue();
applicationRef.current = application;
updateResizeTo();
onInit?.(application);
}, [onInit]);
useIsomorphicLayoutEffect(() => {
if (extensions$1) {
const extensionsToHandle = [...extensions$1];
const extensionsState = extensionsRef.current;
for (const extension of extensionsState.values()) {
const extensionIndex = extensionsToHandle.indexOf(extension);
if (extensionIndex === -1) {
extensions.remove(extension);
extensionsState.delete(extension);
}
extensionsToHandle.splice(extensionIndex, 1);
}
for (const extension of extensionsToHandle) {
extensions.add(extension);
extensionsState.add(extension);
}
}
}, [extensions$1]);
useIsomorphicLayoutEffect(() => {
const canvasElement = canvasRef.current;
if (canvasElement) {
let root = roots.get(canvasElement);
if (!root) {
root = createRoot(canvasElement, { onInit: handleInit });
}
root.render(/* @__PURE__ */ jsx(Bridge, { children }), applicationProps);
}
}, [
applicationProps,
children,
handleInit,
resizeTo
]);
useIsomorphicLayoutEffect(() => {
updateResizeTo();
}, [resizeTo]);
useIsomorphicLayoutEffect(() => {
if (defaultTextStyle) {
Object.assign(TextStyle.defaultTextStyle, defaultTextStyle);
} else {
Object.assign(TextStyle.defaultTextStyle, originalDefaultTextStyle);
}
}, [defaultTextStyle]);
useEffect(() => {
const canvasElement = canvasRef.current;
if (canvasElement) {
unqueueForUnmount(canvasElement);
return () => {
queueForUnmount(canvasElement);
};
}
}, []);
return /* @__PURE__ */ jsx(
"canvas",
{
ref: canvasRef,
className
}
);
});
const Application = forwardRef(function ApplicationWrapper(props, ref) {
return /* @__PURE__ */ jsx(FiberProvider, { children: /* @__PURE__ */ jsx(
ApplicationImplementation,
{
ref,
...props
}
) });
});
export { Application };
//# sourceMappingURL=Application.mjs.map