michalochman / react-pixi-fiber Goto Github PK
View Code? Open in Web Editor NEWWrite PixiJS applications using React declarative style.
License: MIT License
Write PixiJS applications using React declarative style.
License: MIT License
I'm implementing server-side rendering while leveraging react-pixi-fiber
, but I'm getting an error (that makes sense) that the window, navigator, document, etc. objects are not available. I've come up with a workaround for this by replace react-pixi-fiber
in the Webpack build process—basically I stubbed out the <Stage />
component and had it just return this.props.children
. This seems to work fine for me, but I was curious if you would be interested in a PR to resolve this issue, or if you'd rather not support SSR.
react-pixi-fiber
Hi Michal,
This is a question, I believe I can't add the question label directly.
I have been struggling with applying a mask with a CustomPIXIComponent. I have honestly no idea if this works. I thought I'd go ahead and ask you.
The following is my custom PIXI component, which renders a circle and animates along the X-axis:
const Circle = CustomPIXIComponent(
{
// Only necessary argument
customDisplayObject: (_props: any) => new PIXI.Graphics(),
// Apply props in a custom way with customDisplayObject passed as instance
customApplyProps: (
instance: PIXI.Graphics,
oldProps: any,
newProps: any
) => {
instance.clear();
instance.beginFill(oldProps.color, newProps.opacity);
instance.drawCircle(oldProps.y, newProps.x, oldProps.radius);
instance.endFill();
if (oldProps.mask) {
// const mask = PIXI.Sprite.fromImage("https://unsplash.it/200");
// mask.anchor.x = 0.5;
// mask.anchor.y = 0.5;
// mask.position.x = newProps.x;
// mask.position.y = oldProps.y;
// instance.mask = oldProps.mask;
}
}
},
"Circle"
);
Which, in my render method, looks like this:
public render() {
return (
<Container>
<Circle
x={this.bigCircleX}
y={this.props.stageCont
radius={this.bigCircleRadius}
opacity={this.opacity}
color={0xe88d3e}
/>
</Container>
);
}
How do I add a mask from a sprite or image, so that my circle has a 'background'?
I have tried the following:
<Sprite />
inside my <Container />
(with a Pixi.Texture.fromImage
as texture prop), but then, how do I apply this mask to my drawing instance inside CustomPIXIComponent
?PIXI.Sprite
as a mask inside customApplyProps
directly, applying this as instance.mask
, but this does nothing, do I still need to add it to my container?If you would have the time to give me some insights would be awesome. TIA.
Write migration guide from Izzimach/react-pixi.
I wanna set up this for a long term project so I choose typescript. But as I see, currently it support as well for js, jsx only.
Hi,
Currently, if I have a stage that does not change over time, the Pixi.Application will create a ticker and re-render the stage on every frame. I think it does not make much sense and that we should only re-render when the react component re-render, so that using a PureComponent stage would help prevent re-rendering a stage that does not change.
This is what I see, when profiling and doing nothing at all in my browser:
I think in such case the browser should not do any work
Rotating Bunny example crashes.
Invariant Violation
Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.
▶ 26 stack frames were collapsed.
evaluate
/index.js:22:9
19 | }
20 | }
21 |
> 22 | ReactDOM.render(<App />, document.getElementById("root"));
| ^
23 |
View compiled
▶ 10 stack frames were collapsed.
This screen is visible only in development. It will not appear if the app crashes in production.
Open your browser’s developer console to further inspect this error.
This error overlay is powered by 'react-error-overlay' used in 'create-react-app'.
#71 proved that there are certain compatibility issues across different React versions. It would be good if the tests could be run against different versions of React to reduce number of regressions that might get introduced.
Hey @michalochman!
First off, I'd just like to give a huge thanks for this library. I had originally been using @inlet/react-pixi
and the performance was so bad that it'd not only crash Chrome but sometimes my entire computer.
I switched to your library which only took a few minutes and I instantly had 60fps buttery smooth goodness. So massive props!
Anyways, my use case is rendering large amounts of data for a visualization. The key feature is starting with a narrow viewport and then scaling the container to see lots of the data at once.
Once all the data has been rendered, the pan/zoom animation is very responsive and smooth. However, the initial render of 10,000+ graphics and sprites can take a while.
I know react fiber has some async rendering in the works. Have you looked into that at all for your customer pixi renderer? Would it be possible to expose or create some sort of API where I could "chunk" the rendering of my items by passing the renderer a subset of things to render per js frame/render call?
Is there a way to obtain a ref on objects?
I would like to create a native react-pixi target for react-spring, then you could use it to "natively" animate things outside of react. For instance here's an example for react-konva:
using hooks: https://codesandbox.io/s/71xj546m46
using render props: https://codesandbox.io/s/4z2vx0l86x
And this was react-blessed: https://twitter.com/0xca0a/status/1000513216672403456
All i need to enable this is a ref and something to update properties. For instance, here's the kova implementation: https://github.com/drcmda/react-spring/blob/master/src/targets/konva/index.js#L14-L21
Unfortunately ref={r => console.log(r)} returns currently null
, i could still just animate elements with rendering them 60fps with new props, but that is extremely expensive.
It appears that upgrading to v2.9 highlights a type issue:
(18,57): Type 'keyof T' does not satisfy the constraint 'string'.
Type 'string | number | symbol' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
It looks like Diff is expecting a string, but Omit is not specifying that keyof T
should be a string.
also, incredible job with the index.d.ts. there's a lot to learn from here!
I am trying to conditionally remove some rectangles that I'm mapping before hand using the .removeChild and it keeps telling me that it is not a function, is the stage. remove not a function?
Members normally passed to PIXI.Container
should be consumed by Stage
component but they aren't.
<Stage scale={2} />
.Hi!
Seems there's no way to add events to stage.
Since DEFAULT_PROPS
and stage propTypes
doesn't include events key, events is filtered and passed to canvas props.
can I just use stage like other pixi container do?
<Stage pointerdown={handler}>
When running npm install
on the master branch, I get a 404 error because the tar.gz of canvas-prebuilt
is not found for node-v67-linux-x64
According to https://github.com/node-gfx/node-canvas-prebuilt
the canvas-prebuilt package is deprecated. As of version 2, canvas itself bundles prebuilt versions from this repo.
canvas-prebuilt
or canvas
. Is it actually used?npm install
When building react-pixi-fiber with typescript there is an error in the type declarations:
`Failed to compile.
/Applications/MAMP/htdocs/relive/skyhawk-cards/node_modules/react-pixi-fiber/index.d.ts
(154,19): Cannot redeclare block-scoped variable 'CustomPIXIComponent'.`
I'm building with TS with the following config:
{
"compilerOptions": {
"target": "es6",
"module": "commonjs",
"sourceMap": true,
"removeComments": false,
"outDir": "build",
"noImplicitAny": true,
"alwaysStrict": true,
"strictNullChecks": true,
"noUnusedLocals": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "node",
"baseUrl": ".",
"jsx": "react",
"declaration": true,
"allowJs": false
},
"compileOnSave": true
}
react-pixi-fiber version: "0.4.5"
React version: "^16.3.2"
ReactDOM version: "^16.3.2"
PixiJS version: "^4.7.3"
I'm trying to add typing to a class that uses react-pixi-fiber's Sprite and I get the following error:
Type error: Type '{ x: number; y: number; width: number; height: number; texture: Texture; anchor: any; rotation: number; pointerdown: (event: any) => void; interactive: true; buttonMode: true; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Sprite> & Readonly<PropsWithChildren<SpriteProperties>>'.
Property 'pointerdown' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Sprite> & Readonly<PropsWithChildren<SpriteProperties>>'. TS2322
22 |
23 | return (
> 24 | <Sprite
| ^
25 | x={node.x} y={node.y}
26 | width={NODE_SIZE} height={NODE_SIZE}
27 | texture={PIXI.Texture.fromImage(node.track ? node.track.image_cover || DEFAULT_IMAGE_PATH : DEFAULT_IMAGE_PATH)}
Has anyone run into the same or a similar typing issue?
class with offending error
export default class NodeSprite extends React.Component<NodeProps, NodeState> {
onNodeClick = (event: any) => {
// implementation
}
render() {
const { node, currentNode } = this.props;
return (
<Sprite
x={node.x} y={node.y}
width={NODE_SIZE} height={NODE_SIZE}
texture={PIXI.Texture.fromImage(node.track ? node.track.image_cover || DEFAULT_IMAGE_PATH : DEFAULT_IMAGE_PATH)}
anchor={centerAnchor}
pointerdown={this.onNodeClick}
interactive
buttonMode
/>
);
}
}
tsconfig.json
I would like the animations to run off of my own timer, however I can not find documentation for hijacking ticker, and every time I try and call this.props.app.ticker(this.animate) I get undefined errors. Need Help. SOS!
Renderer should be resized when changing width or height of <Stage />
.
Hi,
I'm pretty new to Pixi and therefore my question may be pretty dumb, but how do you manage in react-pixi-fiber to alter the default InteractionManager properties ? I would like to set another interactionFrequency.
The default interaction manager is usually located at renderer.plugins.interaction
.
Thanks for your help,
Eld0w
Hi,
I was just wondering if there is a way to apply a transformation matrix to the entire stage, or a specific collection.
I have a couple of components, similar to the Rectangle
in the example, and I have a regular transformation matrix that I would like to apply to all of them, is there any way to do this?
Thanks for your work on this library!
Adding "react-pixi-fiber" to build via "yarn add react-pixi-fiber" fails to install.
First it failed with 'babel' is not recognized as an internal or external command.
so i installed the babel cli
After this it runs babel src/ReactPixiFiber.js -o dist/react-pixi-fiber.development.js
which seems to succeed, then the following error is given.
Error: ENOENT: no such file or directory, open '...react-sandbox\node_modules\react-pixi-fiber\dist\react-pixi-fiber.development.js'
package.json:
"jquery": "^3.2.1",
"pixi.js": "^4.6.2",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-router-dom": "^4.2.2",
"react-scripts": "1.1.0",
"three": "^0.89.0"
Have tried this on two machines, one of which already had babel installed. Same result for each. Build is a fresh react install.
It should be possible to pass some props to rendered <canvas>
through Stage component
I created a new project with create-react-app and added the minimum reqs to get React and Pixi working together (I love react-pixi-fiber btw.) Then I use the shared ticker from the Pixi app to update a state in a React Component. This causes a lot of listeners to be created (6 per frame) and what seems to be a memory leak as the heap grows.
I tried not rendering anything and then it seems to not leak.
Thanks for supporting this library as I'm fairly new to React and HTML gaming!
Using Windows 10 Pro
Installed Yarn via Chocolatey
Follow the instruction via readme to run examples and get error -
Module not found: Can't resolve './dist/react-pixi-fiber.development.js' in '...\fiberdemo\react-pixi-fiber\node_modules\react-pixi-fiber'
This is a question:
Let's say I'm using react-pixi-fiber in an app that has server side rendering. As such, I need to import both react-pixi-fiber and pixi.js in componentDidMount
or after doing a check for window
.
In some cases, I'm able to do something like this:
class PixiStage extends React.Component {
state = {
Stage: null,
isBrowser: false
}
async componentDidMount() {
const { Stage } = await import('react-pixi-fiber');
this.setState({
isBrowser: true,
Stage
})
}
render() {
const { isBrowser, Stage } = this.state;
return(
isBrowser ? Stage : null;
);
}
}
However, I'm not able to achieve the same thing with CustomPIXIComponent
. Example:
class PixiMask extends React.Component {
state = {
Mask: null,
isBrowser: false
}
async componentDidMount() {
const PIXI = await import('pixi.js');
const { CustomPIXIComponent } = await import('react-pixi-fiber');
const type = 'Mask';
const circle = (x, y, r) => {
const g = new PIXI.Graphics();
g.clear();
g.beginFill();
g.drawCircle(x, y, r);
g.endFill();
return g;
};
const behavior = {
customDisplayObject: ({ size, stage: { height, width } }) => {
const container = new PIXI.Container();
container.mask = circle(width / 2, height / 2, size / 2);
return container;
},
customApplyProps: (
instance,
oldprops,
{ size, stage: { height, width } }
) => (instance.mask = circle(width / 2, height / 2, size / 2))
};
const Mask = CustomPIXIComponent(behavior, type);
this.setState({
isBrowser: true,
Mask
});
}
render() {
const { isBrowser, Mask } = this.state;
return(
isBrowser ? Mask : null;
);
}
}
throws the following error:
Uncaught Error: ReactPixiFiber does not support text instances. Use Text component instead.
I was just curious to know if there was a "right" way to do this that I'm not quite getting?
And thanks for all your work on this library, which has been an absolute joy to work with.
This is not an issue, I just want to get some idea how I should go about it. I have a game developed in Pixi and want to port it on react native. From creating views, tweening objects and having interactive buttons there are many components in the game. I can take the help of react-pixi-fibre. Please guide what are the things I need to create via the react-pixi-fibre. What's the most efficient way.
React Pixi Fiber should provide standalone render
method so it can be used without react-dom
dependency.
Update according to facebook/react#11970
Is there a performant way to create a drag/pan function using React + Pixi + react-pixi-fiber?
My process is as follows:
The resulting pan is a bit slow/choppy on desktop, but really slow and choppy on mobile.
I tried implementing the same thing using PIXI directly and without using my React component's state, and performance was waay smoother.
However I think the react-pixi-fiber declarative component approach to writing Pixi apps is waay nicer and waay easier to read.
I think the problem is I'm thrashing setState in my onMove functions, and it's getting bogged down.
This performance issue seems like it could be a big problem for many applications though, as most Pixi apps need to modify positions and other properties in realtime (moving characters in games, etc.).
Does anyone know of a performant way to update Sprite/Collection properties in realtime? (Probably without using React's state)
I'm worried that defeats the purpose of declaring your Pixi Stage in a component-based way, but hopefully there'll be a solution to this.
Hi!
I have an issue with a CustomPIXIComponent.
When my component state is refreshed, CustomPIXIComponent inside it, is not.
import Graphics from './Graphics'
// .....
render() (
// render method is getting called for re-rendering
this.state.arrows.map(arrow => (
<Graphics
key={`${arrow.from.id}-${arrow.to.id}`}
from={arrow.from}
to={arrow.to}
/>
))
)
import { CustomPIXIComponent } from 'react-pixi-fiber'
import * as PIXI from 'pixi.js'
const TYPE = 'Arrow'
export const behavior = {
customDisplayObject: () => new PIXI.Graphics(),
customApplyProps(instance, oldProps, newProps) {
// but this is not called
this.applyDisplayObjectProps(oldProps, newProps)
}
}
export default CustomPIXIComponent(behavior, TYPE)
Probably I shouldn't expect CustomPIXIComponent to re-apply props.
Any advice on how to do this?
is it possible to deal with DisplacementFilter in react-pixi-fiber to do a ripple effet.
to do something like that :
// get our displacement map (image)
var displacementSprite = PIXI.Sprite.fromImage("images/filters/water.png");
// set to repeat in a tiled patern
displacementSprite.texture.baseTexture.wrapMode = PIXI.WRAP_MODES.REPEAT;
// set filter to sprite container
var displacementFilter = new PIXI.filters.DisplacementFilter(displacementSprite);
// Add our filter and sprites to stage
stage.filters = [displacementFilter];
stage.addChild(displacementSprite);
stage.addChild(image);
Thanks for your answer
Yves
How do you use Context
in TypeScript? By reading this paragraph it looks like I can use either withApp
(HOC) or the Context
API directly. Looking in the index.d.ts
file it does not expose anything so importing either fails:
import { AppContext, withApp } from "react-pixi-fiber"
0.5.0
16.5.2
16.5.2
4.8.2
It should be possible to pass all PIXI.Application options through Stage component
I'm having issues using redux connect
on react-pixi-fiber components if the redux provider is not a child of the Stage
component.
The following setup works for me:
// index.js
import Test from 'Test'
const appContainer = document.getElementById('app-container');
render(
<div>
<Test />
<div>...</div>
</div>,
appContainer
);
// Test.js
import TestContainer from 'TestContainer';
const Test = props => {
return(
<Stage>
<Provider store={store}>
<TestContainer />
</Provider>
</Stage>
);
}
export default Test;
// TestContainer.js
const mapStateToProps = state => ({ ...state });
const TestContainer = props => <Container />;
export default connect(mapStateToProps, null)(TestContainer);
However, if I move the Provider
so that it wraps Stage
// Test.js
import TestContainer from 'TestContainer';
const Test = props => {
return(
<Provider store={store}>
<Stage>
<TestContainer />
</Stage>
</Provider>
);
}
export default Test;
I get this error:
Uncaught Error: Could not find "store" in the context of "Connect(TestContainer)". Either wrap the root component in a <Provider>, or pass a custom React context provider to <Provider> and the corresponding React context consumer to Connect(TestContainer) in connect options.
Ideally I'd like
// index.js
import Test from 'Test'
const appContainer = document.getElementById('app-container');
render(
<Provider store={store}>
<div>
<Test />
<div>...</div>
</div>
<Provider>,
appContainer
);
// Test.js
import TestContainer from 'TestContainer';
const Test = props => {
return(
<Stage>
<TestContainer />
</Stage>
);
}
export default connect(mapStateToProps)(Test);
But it gives me the same error as above.
I can work around this by not using connect
on TestContainer
and instead just passing props down to it (When the redux Provider
is used in index.js
, the connected Test
component does have access to the props from the store), but it would be simpler to use it with connect.
I came across this issue in a similar project (that references pixi-react-fiber, so may be at least partially based on it). Comments there indicate that it's a problem with context in general and not specifically redux. The empty objects here and here look like it might be something similar.
I did a little debugging, but couldn't figure anything out. If this is a solvable issue, I'd love to help out if any contributors could give me some pointers.
Passing React's new Context API Provider to the react-pixi-fiber render method throws:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
I've decided to make use of React's new context API to pass the props of my stage around easily. This seemed most appropiate for me top-level, which is where my render method from react-pixi-fiber lives. Whenever I pass my context provider as the first argument with children, it throws the error above.
render(
(
<StageContext.Provider value={this.stageContext}>
<Card
timeline={this.cardTimeline}
data={this.props.data}
reliveIcon={this.props.reliveIcon}
stageContext={this.stageContext}
/>
</StageContext.Provider>
) as any,
this.stage
);
(Just passing my Card component works however)
Note:
Thanks in advance!
This is not an issue, I just want to get some idea how I should go about it. I have a game developed in Pixi and want to port it on react native. From creating views, tweening objects and having interactive buttons there are many components in the game. I can take the help of react-pixi-fibre. Please guide what are the things I need to create via the react-pixi-fibre. What's the most efficient way.
My app is hogging power. When I look at a perf recording I see constant GPU activity even when there are no state changes. I'd like to use react-pixi-fiber in such a way as it only re-renders as needed. I've tried turning off autostart, enabling the shared ticker, and calling .update() on the ticker in a few places but this is buggy and doesn't feel like the right way.
What is the proper way to make sure that RPF is only asking pixi to re-render when something has changed?
Thanks in advance!
HI!
ReactDOM
has a unstable_batchedUpdates
API to batch setState
out of React context.
In react-pixi-fiber
, if the React Pixi Fiber renderer is exported, I can get the batchedUpdates
from it's instance, But seems it's not.( I think React Pixi Fiber renderer should be the internal.
So can expose the batchedUpdates
API? But it's a unstable API, maybe someday it'll be implemented and removed.
Any advise to do this?
I'm trying to set the ticker for some animation that is driven by a video player.
Using the most recent version of react-scripts, I have issues with the customPIXI example.
TypeError: Cannot set property 'dragStart' of undefined
Container.customDidAttach [as _customDidAttach]
src/CustomPIXIComponentExample/DraggableContainer.js:12
9 | instance.cursor = "pointer";
10 |
11 | let draggedObject = null;
12 | this.dragStart = () => {
| ^ 13 | draggedObject = instance;
14 | if (typeof instance.onDragStart === "function") instance.onDragStart(instance);
15 | };
Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue
import React, { Component } from 'react';
import { Stage } from "react-pixi-fiber";
class TOScada extends Component {
constructor(props){
super()
this.state = {
width: 0,
height: 0
}
}
render() {
return (
<div>
<Stage width={800} height={600} options={{ backgroundColor: 0x10bb99 }}>
</Stage>
</div>
);
}
}
export default TOScada;
2.Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue
Provide some additional library-level helpers to make working with this library easier. Previous conversion is in #16.
Examples:
Stage.childContextTypes
for consumer use.React.Component
that provides context types (example, tests)React.StatelessComponent
with context types (example, tests)React.Component
or React.StatelessComponent
(example, tests)Hi there, I think a useful feature to implement in react-pixi-fiber would be to create props for the PixiJS's onPointer__ events. I don't believe this would be a particularly complex addition, just creating a new prop that passes it's callback function to both an onTouch__ and onMouse__ function.
If you're super busy, I'd be happy to take a crack at contributing a solution. This project has been very useful for my project thus far and I'd love to contribute some actual code.
As a developers/users of the framework, it would be great if the "CustomPixiComponent" got ported to react-pixi-fiber.
First of all, thank you for this wonderful library.
I never write WebGL so declarative.
I was wondering if you can help to add spine support.
This is the library: https://github.com/pixijs/pixi-spine
<Spine src={pathToSpineJson} />
Something looks like this will be great, thank you!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.