diff --git a/README.md b/README.md index 8e004776..1835a4ca 100644 --- a/README.md +++ b/README.md @@ -126,11 +126,15 @@ Setting `attachToDevtools` to `true` will automatically attach the application t ###### `defaultTextStyle` -`defaultTextStyle` is a convenience property. Whatever is passed will automatically be assigned to Pixi.js's[`TextStyle.defaultTextStyle`](https://pixijs.download/release/docs/text.TextStyle.html#defaultTextStyle). +`defaultTextStyle` is a convenience property. Whatever is passed will automatically be assigned to Pixi.js's [`TextStyle.defaultTextStyle`](https://pixijs.download/release/docs/text.TextStyle.html#defaultTextStyle). > [!NOTE] > This property **is not retroactive**. It will only apply to text components created after `defaultTextStyle` is set. Any text components created before setting `defaultTextStyle` will retain the base styles they had before `defaultTextStyle` was changed. +###### `extensions` + +`extensions` is an array of extensions to be loaded. Adding and removing items from this array will automatically load/unload the extensions. The first time this is handled happens before the application is initialised. See Pixi.js's [`extensions`](https://pixijs.download/release/docs/extensions.html) documentation for more info on extensions. + ###### `resizeTo` The `` component supports the `resizeTo` property, with some additional functionality: it can accept any HTML element **or** it can take a React `ref` directly. diff --git a/src/components/Application.ts b/src/components/Application.ts index 571278f3..e859df67 100644 --- a/src/components/Application.ts +++ b/src/components/Application.ts @@ -1,20 +1,21 @@ -import { TextStyle } from 'pixi.js'; +import { + extensions as PixiExtensions, + TextStyle, +} from 'pixi.js'; import { createElement, forwardRef, + type ForwardRefRenderFunction, + type MutableRefObject, useCallback, useRef, } from 'react'; import { createRoot } from '../core/createRoot'; import { useIsomorphicLayoutEffect } from '../hooks/useIsomorphicLayoutEffect'; +import { type ApplicationProps } from '../typedefs/ApplicationProps'; +import { type Root } from '../typedefs/Root'; import type { Application as PixiApplication } from 'pixi.js'; -import type { - ForwardRefRenderFunction, - MutableRefObject, -} from 'react'; -import type { ApplicationProps } from '../typedefs/ApplicationProps'; -import type { Root } from '../typedefs/Root'; const originalDefaultTextStyle = { ...TextStyle.defaultTextStyle }; @@ -29,6 +30,7 @@ export const ApplicationFunction: ForwardRefRenderFunction = useRef(null); const canvasRef: MutableRefObject = useRef(null); + const extensionsRef: MutableRefObject> = useRef(new Set()); const rootRef: MutableRefObject = useRef(null); const updateResizeTo = useCallback(() => @@ -95,6 +98,38 @@ export const ApplicationFunction: ForwardRefRenderFunction + { + if (extensions) + { + const extensionsToHandle = [...extensions]; + const extensionsState = extensionsRef.current; + + // Check for extensions that have been removed from the array + for (const extension of extensionsState.values()) + { + const extensionIndex = extensionsToHandle.indexOf(extension); + + // If the extension is no longer in the array, we'll remove it from Pixi.js + if (extensionIndex === -1) + { + PixiExtensions.remove(extension); + extensionsState.delete(extension); + } + + // Since the extension already existed in the state, we can remove it to prevent any further handling + extensionsToHandle.splice(extensionIndex, 1); + } + + // Load any remaining extensions. + for (const extension in extensionsToHandle) + { + PixiExtensions.add(extension); + extensionsState.add(extension); + } + } + }, [extensions]); + useIsomorphicLayoutEffect(() => { const canvasElement = canvasRef.current; diff --git a/src/typedefs/ApplicationProps.ts b/src/typedefs/ApplicationProps.ts index c551ad7d..399e3cd4 100644 --- a/src/typedefs/ApplicationProps.ts +++ b/src/typedefs/ApplicationProps.ts @@ -1,6 +1,7 @@ import type { Application, ApplicationOptions, + ExtensionFormatLoose, TextStyle, TextStyleOptions, } from 'pixi.js'; @@ -24,6 +25,9 @@ export interface BaseApplicationProps /** @description The default style to be applied to text nodes. */ defaultTextStyle?: TextStyle | TextStyleOptions, + /** @description An array of Pixi extensions to be loaded before initialisation. */ + extensions?: (ExtensionFormatLoose | any)[], + /** @description A unique key which allows React to manage this component across changes in parent state. */ key?: Key,