Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature request make resolution dynamic #37

Closed
EloB opened this issue Aug 28, 2018 · 7 comments
Closed

Feature request make resolution dynamic #37

EloB opened this issue Aug 28, 2018 · 7 comments

Comments

@EloB
Copy link
Contributor

EloB commented Aug 28, 2018

Working with resolution really fits React. You can define components and set their sizes and let the resolution do it's magic.

Preferred solution would be to set the Stage to the desired dimension with static values (best practice to use the same dimension as the design files to be able to copy values) for instance 1920x1080 and use resolution to scale each object and canvas. On rare occasions you need the resolution so it would be good if it's being passed as a context.

Example
This is just an ugly hack with key.
http://jsbin.com/heyonevonu/1/edit?js,output

Using this plugin. You gain a lot of easy performance! :)
https://babeljs.io/docs/en/next/babel-plugin-transform-react-constant-elements.html

@inlet
Copy link
Collaborator

inlet commented Aug 30, 2018

Hi @EloB,

Using key is not preferable as it unmounts and mounts a new Stage object each time an update occurs.

Here are my findings:

Scaling the <canvas>

It's better and more performant to scale a complete canvas using css instead of the internal resolution property. The resolution property is nice to have it sharp for retina displays, although you could resize the contents of the PIXI elements at once, perhaps it's a better practise to just simply scale the stage object: app.stage.scale.set(resolution, resolution)

You can also use the autoResize: true option to allow auto resizing the renderer. However, this doesn't scale the content, here's an example: https://jsfiddle.net/bigtimebuddy/wLg7jezb/

Pass resolution as context

You can use the <Provider> for this:

<Stage>
  <Provider>
    { app => (
      <MyComponent resolution={app.renderer.resolution} />
    )}
  </Provider>
</Stage>

Handle resolution changes

Right now the Stage component update the width and height props and reflect these changes to the <canvas> element.
Having the resolution updates on prop change would be awesome, but I couldn't figure out what to implement on resolution change, as this is subjective. For instance in an app I'm working on I'd like to change the internal resolution and reset the interaction manager:

function onResolutionChange() {
  renderer.resolution = resolution
  renderer.rootRenderTarget.resolution = resolution

  renderer.plugins.interaction.destroy()
  renderer.plugins.interaction = new PIXI.interaction.InteractionManager(renderer)
  renderer.resize(this.width, this.height)
}

Would love to hear your thoughts on this.

@EloB
Copy link
Contributor Author

EloB commented Aug 30, 2018

Using key is not preferable as it unmounts and mounts a new Stage object each time an update occurs.

That's why I said it was an ugly hack 😃


It's better and more performant to scale a complete canvas using css instead of the internal resolution property.

That will only scale the bitmap? So it might look blurry? The resolution solution then Graphics values also scaled perfectly. 😃

I seems like Pixi always multiplies with the resolution anyway. So I don't understand why it should be slower... Had a look at their source code. Searched for resolution:
https://github.com/pixijs/pixi.js/search?p=1&q=resolution&unscoped_q=resolution

I know that resolution is used for retina display but Pixi wasn't built for React. So I think this is a best practice if you want to mix these technologies. To be able to optimize for the reconciliation. https://babeljs.io/docs/en/next/babel-plugin-transform-react-constant-elements.html

The first app I built then I passed around a context consumer into each component and multiplied all values myself. The code looked really ugly and can't be any reconciliation optimization at all.

Another idea might be to use scale but I'm not sure how it scales. Will it make my canvas blurry?

const App = ({ children, resolution }) => (
  <Stage width={1920 * resolution} height={1080 * resolution}>
    <ResolutionContext.Provider value={resolution}>
      <Container scale={resolution}>
        {children}
      </Container>
    </ResolutionContext.Provider>
  </Stage>
);

Pass resolution as context

You can use the for this:

That solution doesn't trigger on resolution change because the app never changes? It's the same instance of app passed to the React context.


function onResolutionChange() {
 renderer.resolution = resolution
 renderer.rootRenderTarget.resolution = resolution

 renderer.plugins.interaction.destroy()
 renderer.plugins.interaction = new PIXI.interaction.InteractionManager(renderer)
 renderer.resize(this.width, this.height)
}

Haven’t tried it but looks good to me 😃

@inlet
Copy link
Collaborator

inlet commented Sep 13, 2018

That will only scale the bitmap? So it might look blurry? The resolution solution then Graphics values also scaled perfectly. 😃

Yes you're right, I'm afraid using CSS might blur the canvas if you're scaling it up.

I seems like Pixi always multiplies with the resolution anyway. So I don't understand why it should be slower... Had a look at their source code. Searched for resolution.

Yes it's true that the resolution is internally used to multiply it with the component dimensions, but using the resolution property for scaling things up/down doesn't feel right to me. 😉

Solution

Ideally the Stage could listen for prop resolution change and triggers a render. But killing the interaction manager and resize the canvas accordingly might not be a good solution for common projects.

If you'd like you can create a PR and see if we can come up with a good solution?

@EloB
Copy link
Contributor Author

EloB commented Sep 14, 2018

I can agree that resolution way of scaling things feels a bit odd but I would say it's the best way of doing React PIXI if you want performance and readability! :)

@inlet
Copy link
Collaborator

inlet commented Sep 14, 2018

Feel free to create a PR and collaborate on it together 😉

@inlet
Copy link
Collaborator

inlet commented Sep 28, 2018

I'm closing this issue, again feel free to create a PR with a solution and we'll work on it together and merge it in this codebase. 😃

@inlet inlet closed this as completed Sep 28, 2018
@EloB
Copy link
Contributor Author

EloB commented Sep 28, 2018

When I have some time I will try todo something :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants