All Projects → michalochman → React Pixi Fiber

michalochman / React Pixi Fiber

Licence: mit
Write PixiJS applications using React declarative style.

Programming Languages

javascript
184084 projects - #8 most used programming language

Projects that are alternatives of or similar to React Pixi Fiber

Pixi.js
The HTML5 Creation Engine: Create beautiful digital content with the fastest, most flexible 2D WebGL renderer.
Stars: ✭ 34,982 (+6058.8%)
Mutual labels:  renderer, pixijs, pixi
Pixi Haxe
Externs of Pixi.js for Haxe
Stars: ✭ 175 (-69.19%)
Mutual labels:  renderer, pixijs, pixi
Pixi Seed
Pixi.js project seed with ES6 and webpack
Stars: ✭ 149 (-73.77%)
Mutual labels:  pixijs, pixi
Gown.js
UI system for pixi.js inspired by feathers-ui
Stars: ✭ 195 (-65.67%)
Mutual labels:  pixijs, pixi
React Pixi
Write PIXI apps using React declarative style
Stars: ✭ 1,031 (+81.51%)
Mutual labels:  renderer, pixi
D Zone
An ambient life simulation driven by user activity within a Discord server
Stars: ✭ 466 (-17.96%)
Mutual labels:  pixijs, pixi
Pixi Sound
WebAudio API playback library, with filters. Modern audio playback for modern browsers.
Stars: ✭ 201 (-64.61%)
Mutual labels:  pixijs, pixi
pixijs-ts-boilerplate
Just another PixiJS Typescript Boilerplate with some basic functionalities
Stars: ✭ 54 (-90.49%)
Mutual labels:  pixijs, pixi
pixi-miniprogram
一个可运行于微信小程序的PIXI引擎,通过模拟window环境,有些功能小程序无法模拟,就直接修改了PIXI引擎代码,最终使得PIXI引擎正常运行在小程序上
Stars: ✭ 72 (-87.32%)
Mutual labels:  pixijs, pixi
pixi-shim
PIXI.js Back-End "shim". For mocking Canvas in Node.js with ❤️
Stars: ✭ 45 (-92.08%)
Mutual labels:  pixijs, pixi
Leaflet.pixioverlay
Bring Pixi.js power to Leaflet maps
Stars: ✭ 264 (-53.52%)
Mutual labels:  pixijs, pixi
pixi-omber-gltf2-vector
Pixi.js library for using vector art created in Omber that's saved in glTF 2.0 format
Stars: ✭ 13 (-97.71%)
Mutual labels:  pixijs, pixi
Pixi Live2d
Display live2D model as a sprite in pixi.js.
Stars: ✭ 537 (-5.46%)
Mutual labels:  pixijs, pixi
Miox
Modern infrastructure of complex SPA
Stars: ✭ 374 (-34.15%)
Mutual labels:  renderer
Vkhr
Real-Time Hybrid Hair Rendering using Vulkan™
Stars: ✭ 353 (-37.85%)
Mutual labels:  renderer
Free Tex Packer
Free texture packer
Stars: ✭ 337 (-40.67%)
Mutual labels:  pixi
Pixi Viewport
A highly configurable viewport/2D camera designed to work with pixi.js
Stars: ✭ 532 (-6.34%)
Mutual labels:  pixi
Detect Gpu
Classifies GPUs based on their 3D rendering benchmark score allowing the developer to provide sensible default settings for graphically intensive applications.
Stars: ✭ 460 (-19.01%)
Mutual labels:  pixijs
Metacar
A reinforcement learning environment for self-driving cars in the browser.
Stars: ✭ 337 (-40.67%)
Mutual labels:  pixijs
Psd.rb
Parse Photoshop files in Ruby with ease
Stars: ✭ 3,092 (+444.37%)
Mutual labels:  renderer

ReactPixiFiber – React Fiber renderer for PixiJS

npm License CircleCI codecov styled with prettier gitter

ReactPixiFiber is a JavaScript library for writing PixiJS applications using React declarative style in React 16 and React 17.

For React <16.0.0 see react-pixi.

Demo

See Rotating Bunny demo.

Usage

With ReactDOM

import { render } from "react-dom";
import { Sprite, Stage } from "react-pixi-fiber";
import bunny from "./bunny.png";

function Bunny(props) {
  return <Sprite texture={PIXI.Texture.from(bunny)} {...props} />;
}

render(
  <Stage options={{ backgroundColor: 0x10bb99, height: 600, width: 800 }}>
    <Bunny x={200} y={200} />
  </Stage>,
  document.getElementById("container")
);

This example will render PIXI.Sprite object into a Root Container of PIXI.Application on the page.

The HTML-like syntax; called JSX is not required to use with this renderer, but it makes code more readable. You can use Babel with a React preset to convert JSX into native JavaScript.

Without ReactDOM

import { render, Text } from "react-pixi-fiber";
import * as PIXI from "pixi.js";

// Setup PixiJS Application
const canvasElement = document.getElementById("container")
const app = new PIXI.Application({
  backgroundColor: 0x10bb99,
  view: canvasElement,
  width: 800,
  height: 600,
});

render(
  <Text text="Hello World!" x={200} y={200} />, 
  app.stage
);

This example will render PIXI.Text object into a Root Container of PIXI Application (created as app) inside the <canvas id="container"></canvas> element on the page.

Running Examples

  1. Run yarn install (or npm install) in the repository root.
  2. Run yarn install (or npm install) in the examples directory.
  3. Run yarn start (or npm run start) in the examples directory.
  4. Wait few seconds and browse examples that will open in new browser window.

Installing

The current version assumes React >16.0.0 and PixiJS >4.4.0

yarn add react-pixi-fiber

or

npm install react-pixi-fiber --save

This package works flawlessly with Create React App – see examples above, they already use it.

Migrating from react-pixi

It is possible to use React Pixi Fiber as a drop-in replacement for react-pixi.

There are two options:

Changing import / require statements

Change:

import ReactPIXI from "react-pixi";
// or
const ReactPIXI = require("react-pixi");

to:

import ReactPIXI from "react-pixi-fiber/react-pixi-alias";
// or
const ReactPIXI = require("react-pixi-fiber/react-pixi-alias");

Using webpack resolve alias

resolve: {
  alias: {
    'react-pixi$': 'react-pixi-fiber/react-pixi-alias'
  }
}

API

Components

React Pixi Fiber currently supports following components:

<Stage />

Renders Root Container of any PIXI.Application.

Expects one the following props:

<Container />

Renders PIXI.Container.

<Graphics />

Renders PIXI.Graphics.

<ParticleContainer />

Renders PIXI.particles.ParticleContainer.

<Sprite />

Renders PIXI.Sprite.

<TilingSprite />

Renders PIXI.extras.TilingSprite.

<Text />

Renders PIXI.Text.

<BitmapText />

Renders PIXI.extras.BitmapText.

<NineSlicePlane />

Renders PIXI.NineSlicePlane.

Props

Similarly to ReactDOM in React 16, ReactPixiFiber is not ignoring unknown PIXI.DisplayObject members – they are all passed through. You can read more about Unknown Prop Warning in ReactDOM, however ReactPixiFiber will not warn you about unknown members.

Setting values for Point and ObservablePoint types

For setting properties on PixiJS types that are either PIXI.Points or PIXI.ObservablePoints you can use either and array of integers or a comma-separated string of integers in the following forms: [x,y], "x,y", [i], "i".

In the case where two integers are provided, the first will be applied to the x coordinate and the second will be applied to the y coordinate. In the case where a single integer if provided, it will be applied to both coordinates.

You can still create your own PIXI Point or ObservablePoint objects and assign them directly to the property. These won't actually replace the property but they will be applied using the original object's .copy() method.

Context – Accessing PIXI.Application instance created by <Stage />

PIXI.Application is automatically provided using the following definition (either as a prop or in context):

  • app – an instance of PixiJS Application, with properties like:
    • loader – Loader instance to help with asset loading,
    • renderer – WebGL or CanvasRenderer,
    • ticker – Ticker for doing render updates,
    • view – reference to the renderer's canvas element.
Using withApp Higher-Order Component (with all React versions)

To get app prop in your component you may wrap it with withApp higher-order component:

import { render } from "react-dom";
import { Sprite, Stage, withApp } from "react-pixi-fiber";
import bunny from "./bunny.png";

class RotatingBunny extends Component {
  state = {
    rotation: 0,
  };

  componentDidMount() {
    // Note that `app` prop is coming through `withApp` HoC
    this.props.app.ticker.add(this.animate);
  }

  componentWillUnmount() {
    this.props.app.ticker.remove(this.animate);
  }

  animate = delta => {
    this.setState(state => ({
      rotation: state.rotation + 0.1 * delta,
    }));
  };

  render() {
    return (
      <Sprite 
        {...this.props}
        texture={PIXI.Texture.from(bunny)}
        rotation={this.state.rotation} 
      />
    );
  }
}
RotatingBunny.propTypes = {
  app: PropTypes.object.isRequired,
};

const RotatingBunnyWithApp = withApp(RotatingBunny);

render(
  <Stage options={{ backgroundColor: 0x10bb99, height: 600, width: 800 }}>
    <RotatingBunnyWithApp x={200} y={200} />
  </Stage>,
  document.getElementById("container")
);
Using New Context API directly (with React 16.3.0 and newer)
import { render } from "react-dom";
import { AppContext, Sprite, Stage } from "react-pixi-fiber";
import bunny from "./bunny.png";

class RotatingBunny extends Component {
  state = {
    rotation: 0,
  };

  componentDidMount() {
    // Note that `app` prop is coming directly from AppContext.Consumer
    this.props.app.ticker.add(this.animate);
  }

  componentWillUnmount() {
    this.props.app.ticker.remove(this.animate);
  }

  animate = delta => {
    this.setState(state => ({
      rotation: state.rotation + 0.1 * delta,
    }));
  };

  render() {
    return (
      <Sprite 
        {...this.props}
        texture={PIXI.Texture.from(bunny)}
        rotation={this.state.rotation} 
      />
    );
  }
}
RotatingBunny.propTypes = {
  app: PropTypes.object.isRequired,
};

render(
  <Stage options={{ backgroundColor: 0x10bb99, height: 600, width: 800 }}>
    <AppContext.Consumer>
      {app => (
        <RotatingBunny app={app} x={200} y={200} />
      )}
    </AppContext.Consumer>
  </Stage>,
  document.getElementById("container")
);
Using Legacy Context API directly (with React older than 16.3.0)

This approach is not recommended as it is easier to just use withApp HoC mentioned above.

import { render } from "react-dom";
import { Sprite, Stage } from "react-pixi-fiber";
import bunny from "./bunny.png";

class RotatingBunny extends Component {
  state = {
    rotation: 0,
  };

  componentDidMount() {
    // Note that `app` is coming from context, NOT from props
    this.context.app.ticker.add(this.animate);
  }

  componentWillUnmount() {
    this.context.app.ticker.remove(this.animate);
  }

  animate = delta => {
    this.setState(state => ({
      rotation: state.rotation + 0.1 * delta,
    }));
  };

  render() {
    return (
      <Sprite 
        {...this.props}
        texture={PIXI.Texture.from(bunny)}
        rotation={this.state.rotation} 
      />
    );
  }
}
// Note that here we tell React to apply `app` via legacy Context API
RotatingBunny.childContextTypes = {
  app: PropTypes.object,
};

render(
  <Stage options={{ backgroundColor: 0x10bb99, height: 600, width: 800 }}>
    <RotatingBunny x={200} y={200} />
  </Stage>,
  document.getElementById("container")
);

Custom Components

ReactPixiFiber can recognize your custom components using API compatible with react-pixi.

CustomPIXIComponent(behavior, type) accepts a behavior object with the following 4 properties and a type string.

customDisplayObject(props)

Use this to create an instance of [PIXI.DisplayObject].

This is your entry point to custom components and the only required method. Can be also passed as behavior of type function to CustomPIXIComponent.

customApplyProps(displayObject, oldProps, newProps) (optional)

Use this to apply newProps to your Component in a custom way.

Note: this replaces the default method of transfering props to the specified displayObject. Call this.applyDisplayObjectProps(oldProps,newProps) inside your customApplyProps method if you want that.

customDidAttach(displayObject) (optional)

Use this to do something after displayObject is attached, which happens after componentDidMount lifecycle method.

customWillDetach(displayObject) (optional)

Use this to do something (usually cleanup) before detaching, which happens before componentWillUnmount lifecycle method.

Simple Graphics example

For example, this is how you could implement Rectangle component:

// components/Rectangle.js
import { CustomPIXIComponent } from "react-pixi-fiber";
import * as PIXI from "pixi.js";

const TYPE = "Rectangle";
export const behavior = {
  customDisplayObject: props => new PIXI.Graphics(),
  customApplyProps: function(instance, oldProps, newProps) {
    const { fill, x, y, width, height } = newProps;
    instance.clear();
    instance.beginFill(fill);
    instance.drawRect(x, y, width, height);
    instance.endFill();
  }
};
export default CustomPIXIComponent(behavior, TYPE);
// App.js
import { render } from "react-pixi-fiber";
import * as PIXI from "pixi.js";
import Rectangle from "./components/Rectangle"

// Setup PixiJS Application
const canvasElement = document.getElementById("container")
const app = new PIXI.Application(800, 600, {
  view: canvasElement
});

render(
  <Rectangle
    x={250}
    y={200}
    width={300}
    height={200}
    fill={0xFFFF00}
  />, 
  app.stage
);

Testing

Caveats

React Context API limitations

Because of a React limitation preventing context to pass through renderers, new React Context API (react >= 16.3.0) cannot be used inside Stage inner components. Even if you're not using this feature directly, some of your dependencies may use it (react-redux, material-ui, ...).

A workaround would be to "make a bridge" between default renderer and react-pixi-fiber one. For example:

// use example
export const App = () => {

  return (
    <GameTitleContext.Provider value={'game title'}>
      <GameTitleContext.Consumer>
        {title => <h1>{title}</h1>}
      <GameTitleContext.Consumer>
      
      <ContextBridge
        contexts={[
          GameTitleContext,
          ReactReduxContext,
          OtherContext,
        ]}
        barrierRender={children => (
          <Stage options={{ height: 600, width: 800 }}>
            {children}
          </Stage>
        )}
      >
        <Container>
          <GameTitleContext.Consumer>
            {title => <Text text={title} />}
          </GameTitleContext.Consumer>
        </Container>
      </ContextBridge>
    </GameTitleContext.Provider>
  );
};
// context-bridge component

/*
 * type ContextBridgeProps = {
 *    contexts: React.Context<any>[];
 *    barrierRender: (children: React.ReactElement | null) => React.ReactElement | null;
 *    children: React.ReactNode;
 * };
 */

export const ContextBridge = ({ barrierRender, contexts, children }) => {

    const providers = values => {

        const getValue = i => values[ values.length - 1 - i ];

        return <>
          {contexts.reduce((innerProviders, Context, i) => (
            <Context.Provider value={getValue(i)}>
                {innerProviders}
            </Context.Provider>
          ), children)}
        </>;
    };

    const consumers = contexts.reduce((getChildren, Context) => (
        values => <Context.Consumer>
            {value => getChildren([ ...values, value ])}
        </Context.Consumer>
    ), values => barrierRender(providers(values)));

    return consumers([]);
};

More infos & workarounds: #93 #84 (comment)

FAQ

Is it production ready?

Yes! Awesome!

What version of PixiJS I can use?

Both PixiJS v4 and v5 are supported.

Can I use already existing PIXI.Application?

Yes, you can pass app property to Stage component, e.g. <Stage app={app} />.

Can I migrate from react-pixi?

Yes, it is easy, read migration guide.

Is server-side rendering supported?

No, unfortunately it is not supported right now.

Contributing

The main purpose of this repository is to be able to render PixiJS objects inside React 16 Fiber architecture.

Development of React Pixi Fiber happens in the open on GitHub, and I would be grateful to the community for any contributions, including bug reports and suggestions.

Read below to learn how you can take part in improving React Pixi Fiber.

Code of Conduct

React Pixi Fiber has adopted a Contributor Covenant Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.

Contributing Guide

Read the contributing guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to React Pixi Fiber.

Contact

You can help others and discuss in our gitter channel.

License

ReactPixiFiber is MIT licensed.

Credits

react-pixi

For making PIXI available in React for the first time.

React Fiber Architecture

For deeply explaining the concepts of Fiber architecture.

Building a custom React renderer

For helping me understand how to build an actual renderer.

React ART

On which this renderer was initially based.

React Contributors

For making an awesome project structure and documentation that is used in similar fashon here.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].