Skip to content

Commit

Permalink
Merge pull request #529 from pixijs/add-extensions-support
Browse files Browse the repository at this point in the history
Add support for managing `extensions`
  • Loading branch information
trezy authored Sep 1, 2024
2 parents e808f22 + 2e79fc0 commit 8490ecb
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 8 deletions.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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 `<Application>` component supports the `resizeTo` property, with some additional functionality: it can accept any HTML element **or** it can take a React `ref` directly.
Expand Down
49 changes: 42 additions & 7 deletions src/components/Application.ts
Original file line number Diff line number Diff line change
@@ -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 };

Expand All @@ -29,13 +30,15 @@ export const ApplicationFunction: ForwardRefRenderFunction<PixiApplication, Appl
children,
className,
defaultTextStyle,
extensions,
onInit,
resizeTo,
...applicationProps
} = props;

const applicationRef: MutableRefObject<PixiApplication | null> = useRef(null);
const canvasRef: MutableRefObject<HTMLCanvasElement | null> = useRef(null);
const extensionsRef: MutableRefObject<Set<any>> = useRef(new Set());
const rootRef: MutableRefObject<Root | null> = useRef(null);

const updateResizeTo = useCallback(() =>
Expand Down Expand Up @@ -95,6 +98,38 @@ export const ApplicationFunction: ForwardRefRenderFunction<PixiApplication, Appl
}
}, [onInit]);

useIsomorphicLayoutEffect(() =>
{
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;
Expand Down
4 changes: 4 additions & 0 deletions src/typedefs/ApplicationProps.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type {
Application,
ApplicationOptions,
ExtensionFormatLoose,
TextStyle,
TextStyleOptions,
} from 'pixi.js';
Expand All @@ -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,

Expand Down

0 comments on commit 8490ecb

Please sign in to comment.