npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

phaser-react-ui

v1.15.1

Published

React interface render for Phaser engine

Downloads

42

Readme

⚡ Phaser React UI

Npm package version Small size Building

Library for render relative game interface using React, connecting it with Phaser through events and context.

Use special hooks for access to game and scenes.

For each scene can be create one interface instance, which is container for all components.

.

Documentation

.

Install

npm i phaser-react-ui

.

Integration

Add interface to scene

const ui = new Interface(scene: Phaser.Scene)

console.log(ui.container) // HTMLDivElement

Interface render

ui.render(
  component: React.FC, 
  props?: object
)

Interface events

scene.events.on(Phaser.Interface.Events.MOUNT, () => {
  console.log('component mounted');
})

Toggle interface interactive

ui.setInteractive(state: boolean)
  • Default: true
  • You can toggle interactive for certain interface elements by CSS-property pointer-events

Remove interface from scene

ui.destroy()
  • When scene is closed, the interface is destroyed automatically

.

Hooks

Get game instance

useGame(): Phaser.Game

Get scene

  • Get scene in which interface was created
useCurrentScene(): Phaser.Scene
  • Get scene by key
useScene(key: string): Phaser.Scene

Subscribe to scene update

useSceneUpdate(
  scene: Phaser.Scene, 
  callback: () => void, 
  depends: any[]
)

Subscribe to event

useEvent(
  emitter: Phaser.Events.EventEmitter, 
  event: string,
  callback: () => void, 
  depends: any[]
)

Position relative to camera

useRelativePosition(params: { 
  x: number,
  y: number,
  camera?: Phaser.Cameras.Scene2D.Camera
}): React.MutableRefObject<HTMLElement>

Scale relative to canvas size

useRelativeScale(params: { 
  target: number, 
  min?: number,
  max?: number,
  round?: boolean
}): React.MutableRefObject<HTMLElement>

Get texture source image

useTexture(key: string): HTMLImageElement

Get actual media query result

useMatchMedia(query: string): boolean

Check if platform is mobile

useMobilePlatform(): boolean

Use adaptive click event on target element

useClick(
  ref: React.RefObject,
  type: 'up' | 'down',
  callback: Function,
  depends: any[]
)

Use adaptive click event outside target element

useClickOutside(
  ref: React.RefObject,
  callback: Function,
  depends: any[]
)

Use adaptive interaction flow

useInteraction(
  ref: React.RefObject,
  callback?: Function,
  depends?: any[]
): boolean

.

Components

Position relative to camera

<RelativePosition 
  x={number} 
  y={number} 
  camera={Phaser.Cameras.Scene2D.Camera?}
>
  ...
</RelativePosition>

Scale relative to canvas size

<RelativeScale 
  target={number} 
  min={number?} 
  max={number?} 
  round={boolean?}
>
  ...
</RelativeScale>

Render texture image

<Texture name={string} />

.

Utils

Safe rerender utils

ifModifiedObject(
  newValue: T, 
  keys?: (keyof T)[]
): (currentValue: T) => T
ifModifiedArray(
  newValue: T[], 
  keys?: (keyof T)[]
): (currentValue: T[]) => T[]
const Component: React.FC = () => {
  const scene = useCurrentScene();
  const [data, setData] = useState({});

  useSceneUpdate(scene, () => {
    const newData = scene.getSomeData();
    // Rerender only if newData is different by data
    setList(ifModifiedObject(newData))
  }, []);
};

.

Example

Create interface component

import { useScene, useSceneUpdate, useEvent } from 'phaser-react-ui';

const PlayerHealth: React.FC = () => {
  const world = useScene('world');

  const [health, setHealth] = useState(0);
  const [isAlive, setAlive] = useState(true);

  useSceneUpdate(world, () => {
    if (isAlive) {
      setHealth(world.player.health);
    }
  }, [isAlive]);

  useEvent(world.player, Phaser.GameObjects.Events.DESTROY, () => {
    setAlive(false);
  }, []);

  return isAlive && (
    <div className='info'>
      {health} HP
    </div>
  );
};

Create components container

import { useRelativeScale } from 'phaser-react-ui';
import { PlayerHealth } from './PlayerHealth';

const ScreenUI: React.FC<Props> = () => {
  const ref = useRelativeScale<HTMLDivElement>({
    target: 1280,
    min: 0.6,
    max: 1.2,
  });

  return (
    <div ref={ref} className='container'>
      <PlayerHealth />
      ...
    </div>
  );
};

ScreenUI.displayName = 'ScreenUI';

Add interface to scene

import { Interface } from 'phaser-react-ui';
import { ScreenUI } from './ScreenUI';

class Screen extends Phaser.Scene {
  private ui: Interface;

  create() {
    this.ui = new Interface(this);
    this.ui.render(ScreenUI);
  }
}