Skip to content

Commit

Permalink
feat: add support for ref on <Application> component
Browse files Browse the repository at this point in the history
  • Loading branch information
trezy committed Jun 23, 2024
1 parent a7274a7 commit 1e029f5
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
34 changes: 24 additions & 10 deletions src/components/Application.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import {
createElement,
forwardRef,
useEffect,
useImperativeHandle,
useRef,
useState,
} from 'react';
import { render } from '../render.js';

/** @typedef {import('pixi.js').Application} Application */
/** @typedef {import('pixi.js').ApplicationOptions} ApplicationOptions */
/** @typedef {import('pixi.js').Application} PixiApplication */
/** @typedef {import('pixi.js').ApplicationOptions} PixiApplicationOptions */
/**
* @template T
* @typedef {import('react').PropsWithChildren<T>} PropsWithChildren
Expand All @@ -30,16 +33,16 @@ import { render } from '../render.js';
* @property {string} [className] CSS classes to be applied to the Pixi Application's canvas element.
*/

/** @typedef {PropsWithChildren<Partial<OmitChildren<ApplicationOptions>>>} ApplicationPropsWithChildren */
/** @typedef {PropsWithRef<{ ref?: RefObject<Application> }>} ApplicationPropsWithRef */
/** @typedef {BaseApplicationProps & ApplicationPropsWithChildren & ApplicationPropsWithRef} ApplicationProps */
/** @typedef {PropsWithChildren<OmitChildren<Partial<PixiApplicationOptions>>>} ApplicationPropsWithChildren */
/** @typedef {PropsWithRef<{ ref?: RefObject<PixiApplication> }>} ApplicationPropsWithRef */
/** @typedef {BaseApplicationProps & ApplicationPropsWithChildren} ApplicationProps */

/**
* Creates a React root and renders a Pixi application.
*
* @param {ApplicationProps} props All props.
* @type {import('react').ForwardRefRenderFunction<PixiApplication, ApplicationProps>}
*/
export function Application(props)
export const ApplicationFunction = (props, forwardedRef) =>
{
const {
children,
Expand All @@ -50,18 +53,29 @@ export function Application(props)
/** @type {RefObject<HTMLCanvasElement>} */
const canvasRef = useRef(null);

const [application, setApplication] = /** @type {PixiApplication} */ useState();

useImperativeHandle(forwardedRef, () => /** @type {PixiApplication} */ /** @type {*} */ (application));

useEffect(() =>
{
const canvasElement = canvasRef.current;

if (canvasElement)
{
render(children, canvasElement, applicationProps);
setApplication(render(children, canvasElement, applicationProps));
}
}, []);
}, [
applicationProps,
children,
]);

return createElement('canvas', {
ref: canvasRef,
className,
});
}
};

ApplicationFunction.displayName = 'Application';

export const Application = forwardRef(ApplicationFunction);
26 changes: 23 additions & 3 deletions src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,28 @@ const context = createContext(null);
const roots = new Map();

/** @typedef {import('pixi.js').ApplicationOptions} ApplicationOptions */
/** @typedef {import('react').PropsWithChildren} PropsWithChildren */
/** @typedef {Partial<PropsWithChildren & ApplicationOptions>} RenderProps */

/**
* @template T
* @typedef {import('react').PropsWithChildren<T>} PropsWithChildren
*/
/**
* @template T
* @typedef {import('react').PropsWithRef<T>} PropsWithRef
*/
/**
* @template T
* @typedef {import('react').RefObject<T>} RefObject
*/

/**
* @template T
* @typedef {import('./typedefs/OmitChildren.js').OmitChildren<T>} OmitChildren
*/

/** @typedef {PropsWithChildren<OmitChildren<ApplicationOptions>>} ApplicationPropsWithChildren */
/** @typedef {PropsWithRef<{ ref: RefObject<Application> }>} ApplicationPropsWithRef */
/** @typedef {Partial<ApplicationPropsWithChildren & ApplicationPropsWithRef & ApplicationOptions>} RenderProps */

/**
* This renders an element to a canvas, creates a renderer, scene, etc.
Expand Down Expand Up @@ -131,5 +151,5 @@ export function render(
() => undefined
);

return state;
return state.app;
}

0 comments on commit 1e029f5

Please sign in to comment.