Jump to content
Search Community

Pixiplugin doesn't seem ready for Pixi v5

Friebel test
Moderator Tag

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

Moving a project, that is using the pixiplugin, from Pixi v4 to Pixi v5, the pixiplugin doesn't seem to work with pixi v5. It is throwing these errors:

'Cannot read property 'DisplayObject' of undefined'. Pixi v5 moved some objects around in the hierarchy, so that's probably the reason.

 

I've been looking for a version supporting pixi v5, but this is the most recent version and on github it doesn't have newer commits either.

 

There are quite a lot pixi animations in this project, so it would be nice to be able to keep using this plugin instead of having to skip this plugin and replace all scaling and rotations to different tweens.

 

Anybody knows if there will be an upgrade/fix for pixi v5 for this pretty handy plugin anytime soon? I otherwise might create a plugin myself for this, but if there's already a fix in the making, or something I am missing here, that would be nice.

 

Thanks in advance!

Link to comment
Share on other sites

Thanks for your quick reaction @OSUblake. Faster than light!

 

Great that there is a way to address pixi 5. registerPIXI doesn't seem to be in the documentation of the plugin https://greensock.com/docs/Plugins/PixiPlugin . So can't really look it up, so I am looking through the plugin-code itself now, because I don't have a full PIXI object to supply.

 

It seems like to use the plugin we need to hand the full PIXI object to it to be able to sniff it's properties/methods. I was hoping I could just add a { VERSION: 5 } object to the registerPIXI function instead, but that doesn't seem to work as it looks like the plugin also want to sniff for available functions inside the PIXI object.

 

Using webpack and direct imports like 

import { Container } from 'pixi.js'

I don't have this full PIXI object available. Only the features I use directly, like 'Container', 'Renderer' and stuff like that.

 

Is there a way to use it in a modular way or do we really need to provide the full PIXI object now to use this plugin? Basically the only thing I wish to use of this plugin is scaling and rotating.

 

(BTW   @GreenSock , I might be missing something or overlook things, but it looks to me like the registerPIXI function isn't documented in the plugin docs. If so, it might help others too to add it to avoid confusion)

 

Thanks again,

Link to comment
Share on other sites

23 minutes ago, Friebel said:

Is there a way to use it in a modular way or do we really need to provide the full PIXI object now to use this plugin? Basically the only thing I wish to use of this plugin is scaling and rotating.

 

 

And you never need the plugin, but scaling and rotation are some of the things it helps simplify.

 

Without the plugin, you would have to do a scaling and rotation animation like this.

 

var tl = new TimelineMax()
  .to(sprite.scale, 1, { x: 2 }, 0)
  .to(sprite.scale, 1, { y: 2 }, 0)
  .to(sprite, 1, { rotation: Math.PI / 180 }, 0)

 

Link to comment
Share on other sites

 

23 minutes ago, OSUblake said:

 

You're supposed to import Pixi like this.

 


import * as PIXI from "pixi.js";

 

I appreciate your help @OSUblake. But I have to respectfully dissagree on this point. I don't want to import everything. And I don't believe we are 'supposed to' do it like that either. I only use some parts of pixijs. Importing per module/object is the whole idea of modular imports. Even if Webpack would still treeshake when importing everything from 'pixi.js' with an asterix (I'm not sure if that's the case, but it might be as it is Webpack), it still makes code more structured, logical and clean to me if I only import what's needed in the module. I think that's a much cleaner and structured way of coding and I value being aware of what is actually in use by the module too. So I'd rather not import * from pixi just to use the pixiplugin.

 

(BTW, We could even import from namespaced modules, like '@pixi/loaders')

 

19 minutes ago, OSUblake said:

 

And you never need the plugin, but scaling and rotation are some of the things it helps simplify.

 

Without the plugin, you would have to do a scaling and rotation animation like this.

 


var tl = new TimelineMax()
  .to(sprite.scale, 1, { x: 2 }, 0)
  .to(sprite.scale, 1, { y: 2 }, 0)
  .to(sprite, 1, { rotation: Math.PI / 180 }, 0)

 

I understand I don't need this plugin and I'm aware it might even be overkill for just using rotation and scale in my case, but also a very helpful plugin in a lot of cases. I also understand how I can do it without it and there is a threshhold in when the plugin is getting useful; and that's with a bigger project that uses a lot of scaling and rotating. Eventhough I don't animate colors in pixi now.

Seeing now the pixiplugin contains a lot of color functions inside I don't use I might decide to create a smaller plugin just for this project and directly address v5 or use onUpdate to set the scaling and rotating from a single animation-object instead. Than I could just use { scaleX, scaleY, rotation} and transform it to .scale.x, .scale.y, .angle in the onUpdate.

 

Thanks for you help. I appreciate it!

Link to comment
Share on other sites

11 minutes ago, OSUblake said:

Oh, it looks like v5 added "angle" for degrees.

http://pixijs.download/release/docs/PIXI.Sprite.html#angle

 

But scaling is still a PIXI.Point object, so it has to be animated separately from other display object properties, like rotation/angle.

Thanks for this extra info and the effort you put into searching for this! 

Link to comment
Share on other sites

Just now, Friebel said:

I appreciate your help @OSUblake. But I have to respectfully dissagree on this point. I don't want to import everything.

 

Don't disagree with me. That's the official recommendation from PixiJS.

https://github.com/pixijs/pixi.js

 

Quote

NPM Install


npm install pixi.js

There is no default export. The correct way to import PixiJS is:


import * as PIXI from 'pixi.js'

 

 

I haven't messed with v5 modules yet, so I don't know how tree shaking will work. Have you tried it yet? If you are importing the actual es modules file from Pixi (pixi.es.js in the lib folder in node_modules), it looks very similar to the GSAP's all.js file, which is tree shakeable.

 

And I wasn't trying to suggest that you skip using the plugin, I was just showing you workarounds.

 

If you don't import PIXI as a namespace, you can always do what the registerPIXI method does. Just add a PIXI object to the window with all the stuff the plugin is looking for.

 

window.PIXI = {
  DisplayObject: DisplayObject
  ...
};

 

 

  • Like 1
Link to comment
Share on other sites

23 minutes ago, OSUblake said:

There is no default export. The correct way to import PixiJS is: 


import * as PIXI from 'pixi.js'

I believe this is a misinterpretation a lot of people have. With this to me they are saying that there is not 'default' export, so it's impossible to do

import PIXI from 'pixi.js'

, so if we'd like to import everything from pixi, we need to 

import * as PIXI from 'pixi.js'

They are not writing or advising we should always import the whole lib. It would also not make much sense to have a default in the pixi lib, because we should be able to import everything per module too.

 

Also take a look here:

https://www.npmjs.com/package/@pixi/sprite

https://www.npmjs.com/package/@pixi/display

etc.

 

import { Sprite } from '@pixi/sprite';
 
const sprite = new Sprite();

That's also their 'official' documentation.

 

So they have npm packages for every single module, pixi namespaced. To even be able to only install the modules you need. Than the other modules aren't even in the node_modules folder. That was one of more goals of pixi 5: being even more modular.

 

But it's also possible to just use 'pixi.js' and import all modules/classes you need from it:

import { Container } from 'pixi.js';

Than you don't need to install all modules as seperate npm modules, but just the pixi.js lib and import from it whatever you need.

 

BTW Greensock remains amazing. I am now creating my own plugin for just the scaling and rotating in pixi using the TEMPLATE_Plugin.js. And that file is full of very insightful help-comments. And there even seem to be a full plugin documentation available on the greensock website.

Thanks @GreenSock Jack! Amazing! 

 

  • Like 2
Link to comment
Share on other sites

24 minutes ago, OSUblake said:

I haven't messed with v5 modules yet, so I don't know how tree shaking will work. Have you tried it yet?

Yes. It works both with the single '@pixi/sprite'-like npm packages as modules as well as loading from 'pixi.js' (installing the pixi.js module).

Link to comment
Share on other sites

38 minutes ago, Friebel said:

 

PixiJS needs several packages to run. See the grayed out ones here.

https://pixijs.io/customize/

 

But I'm not trying to get into the details of PixiJS or how you should import it. You do what you think is necessary, and goes with your coding style. All I'm saying is that in order for the plugin to work, there needs be a global PIXI object, which you can make yourself. 

 

window.PIXI = {
  DisplayObject: DisplayObject
  ...
};

 

You could also pass that object to the registerPIXI plugin to have the same effect.

 

It looks like all it needs is VERSION, DisplayObject, Graphics, and filters.

 

  • Like 1
Link to comment
Share on other sites

17 minutes ago, OSUblake said:

It looks like all it needs is VERSION, DisplayObject, Graphics, and filters.

 

Just by quickly look at the plugin, it looks like you would only have to provide a DisplayObject, which every display object (Container, Sprite, etc) in Pixi inherits from.

 

So do this, and see if it works.

 

window.PIXI = {
  DisplayObject: DisplayObject
};

 

Or this...

 

PixiPlugin.registerPIXI({
  DisplayObject: DisplayOject
});

 

Link to comment
Share on other sites

31 minutes ago, OSUblake said:

 

Just by quickly look at the plugin, it looks like you would only have to provide a DisplayObject, which every display object (Container, Sprite, etc) in Pixi inherits from.

 

So do this, and see if it works.

 


window.PIXI = {
  DisplayObject: DisplayObject
};

 

Or this...

 


PixiPlugin.registerPIXI({
  DisplayObject: DisplayOject
});

 

 

Thanks a lot for your help @OSUBlake. As I wrote above I started creating my own gsap-pixi plugin. That one is finished now and and everything is working fine now! The project is now completely converted from pixi 4 to pixi 5. As extra bonus with this I skipped the color functions I don't use and directly use the angle in degrees without the radians to degrees conversion for rotations. Also no checking for pixi version, as I know I'm using version 5. And so don't need to create a dummy PIXI object. So now that I finished that one and everything is done I might as well keep that one ;) 

(BTW: the skew in pixijs is still in radians. For some reason they didn't added an extra function to that to enter values in degrees)

 

 Also nice to know now how to write gsap plugins. Although the existing gsap plugins are great and never really missed something. Thanks again! In case I need to use the full plugin with color methods and everything for another project I'm probably going to use your method.

  • Like 1
Link to comment
Share on other sites

2 hours ago, OSUblake said:

Oh, it looks like v5 added "angle" for degrees.

 

I totally forgot I recommended that. ?

https://github.com/pixijs/pixi.js/issues/4133#issuecomment-312403814

 

 

30 minutes ago, Friebel said:

BTW: the skew in pixijs is still in radians. For some reason they didn't added an extra function to that to enter values in degrees

 

They were going to use degrees, but I think they changed it so it wouldn't be a breaking change.

https://github.com/pixijs/pixi.js/pull/4579

 

30 minutes ago, Friebel said:

 Also nice to know now how to write gsap plugins. Although the existing gsap plugins are great and never really missed something. Thanks again!

 

There's a new version of GSAP coming soon, and plugins seem to be much easier to write. There's even a video explaining how they work. ?

 

Link to comment
Share on other sites

BTW I'm doing some tests and with Webpack it doesn't matter at all if we import from 'pixi.js' or from 'pixi.js/lib/pixi.es'. The output has the exact same size.

 

Also it looks like when importing from either of those everything is included in the package. ALso the modules that has not been imported, like the particles module, which should definitely shouldn't be in there as I don't import it. So I'm going to convert the imports to the namespaces @pixi ones to see if that helps in leaving out the unwanted parts. As pixi is always pretty big (twice as big as Easel-projects, still with v5, eventhough it's 100kB smaller than v4 for most projects I use pixi for).

 

My goal is to have the smallest output size possible. I once recreated this project from an EaselJs project, and it's literally twice as big build with Pixi v5 (with dropped canvas-support) as with EaslJs (with no webGl support). So although I understand the underlying webGL code is a lot, it should be possible to have a much smaller output than this.

 

BTW, I just read the github PR about pixi's skew according to changing it to degrees. And indeed they decided to leave it with radians. Which is a fine decision to me. Makes calculations as fast as possible at least. And it's easy to create a degr2rad function anyway, or just use a calculator.

 

Anway, this is not really about greensock anymore, although pixijs is much fun an very interesting :) . Keep up the great work. I'm trying out the modular versions later to see if that makes the output smaller (which I really hope).

Link to comment
Share on other sites

4 minutes ago, Friebel said:

Also it looks like when importing from either of those everything is included in the package. ALso the modules that has not been imported, like the particles module, which should definitely shouldn't be in there as I don't import it.

 

Interesting. Is everything in the production build, or just the dev build? Like I said earlier, I haven't worked with modules (the tree shaking part) with PixiJS, so I don't know what should happen.

 

To minimize the build, select what you want from here. It will show you what to import. Be sure to click on the "Bundler" button in the top-right.

https://pixijs.io/customize/

 

4 minutes ago, Friebel said:

Would be great if that supports real es6 imports and es6 internal code and we don't need the 'const required = []' constructions anymore.

 

That has nothing to do with es6. Tree shaking is an optimization done by build tools. You will now be required to register plugins. 

 

gsap.registerPlugin(SomePlugin, AnotherPlugin);

 

That is the only way to prevent tree shaking from removing plugins that you don't call directly. That will also prevent every plugin you import from becoming a global when using modules. Currently everything you import is global.

 

  • Like 2
Link to comment
Share on other sites

3 hours ago, Friebel said:

registerPIXI doesn't seem to be in the documentation of the plugin

Sorry about that. I have added it and it will be included in the next version of the GSAP documentation.

 

1 hour ago, Friebel said:

I started creating my own gsap-pixi plugin. That one is finished now and and everything is working fine now!

Would you mind sharing the code for that? Perhaps we can learn from it and upgrade our PixiPlugin (when we have time to).

  • Thanks 1
Link to comment
Share on other sites

11 minutes ago, ZachSaucier said:

Sorry about that. I have added it and it will be included in the next version of the GSAP documentation.

 

It's not in the current version of the docs, and it should be probably be on the main page of the plugin page showing how to use, just like this. I wouldn't expect that many users to actually click on the registerPIXI method.

 

import * as PIXI from "pixi.js";
import { PixiPlugin } from "gsap/PixiPlugin";

PixiPlugin.registerPIXI(PIXI);

 

21 minutes ago, ZachSaucier said:

Would you mind sharing the code for that? Perhaps we can learn from it and upgrade our PixiPlugin (when we have time to).

 

He did scaling, which the plugin currently does.

  • Like 2
Link to comment
Share on other sites

10 hours ago, OSUblake said:

There's a new version of GSAP coming soon, and plugins seem to be much easier to write. There's even a video explaining how they work. ?

:)

 

Yep, if you'd like early access, just shoot me a direct message or something. I think you're gonna dig what's coming next. 

  • Like 1
Link to comment
Share on other sites

17 hours ago, ZachSaucier said:

Would you mind sharing the code for that? Perhaps we can learn from it and upgrade our PixiPlugin (when we have time to).

 

Yes, here it is; I decided to stripdown the Greensock PixiPlugin to position, scale, skew, pivot, anchor, tilePosition and tileScale, converted to ES6 as far as possible and I removed the pixi version check, so it works directly with Pixi5 (the thing I needed).

 

It uses pixi 5's  'angle' instead of 'rotation' to skip the degrees to radians conversion. I also skipped some other things I don't use on this project, like the color tweens (which looks nice, but I never used it with pixi so that is some redundant code for my projects I'd rather not include in production builds if I was working on the file anyway) and removed the degrees to radians conversion for skew, because I already have a degr2rad() function in my project to use if needed, so now I always pass the original values directly to pixi without conversion.

 

So basically it's the PixiPlugin light, but now without PIXI versionchecks and build directly for Pixi 5. I like it that way, because I rather have a plugin per pixi version instead of one plugin addressing them all with sniffing. Because I only use one pixi version per project. 

 

/* eslint-disable no-restricted-syntax */
/* eslint-disable guard-for-in */
/* eslint-disable no-underscore-dangle */

import { _gsScope } from 'gsap/TweenLite';

const SimplePixi5Plugin = _gsScope._gsDefine.plugin({
    propName: 'pixi',
    priority: 0,
    API: 2,
    global: true,
    version: '1.0.1',

    init: function init(target, values, tween, index) {
        let p;
        let axis;

        const xyContexts = [
            'position',
            'scale',
            'skew',
            'pivot',
            'anchor',
            'tilePosition',
            'tileScale',
        ];

        const contexts = {
            x: 'position',
            y: 'position',
            tileX: 'tilePosition',
            tileY: 'tilePosition',
        };

        for (let i = 0; i < xyContexts.length; i++) {
            p = xyContexts[i];
            contexts[`${p}X`] = p;
            contexts[`${p}Y`] = p;
        }

        let context;
        let value;
        for (p in values) {
            context = contexts[p];
            value = values[p];

            if (typeof value === 'function') {
                value = value(index || 0, target);
            }

            if (context) {
                axis = (p.charAt(p.length - 1).toLowerCase().indexOf('x') !== -1) ? 'x' : 'y';
                this._addTween(target[context], axis, target[context][axis], value, p);
            } else if (p === 'scale'
                || p === 'anchor'
                || p === 'pivot'
                || p === 'tileScale') {
                this._addTween(target[p], 'x', target[p].x, value, `${p}X`);
                this._addTween(target[p], 'y', target[p].y, value, `${p}Y`);
            } else if (p === 'angle') {
                this._addTween(target, p, target.angle, value, p);
            }

            this._overwriteProps.push(p);
        }

        return true;
    },
});

export { SimplePixi5Plugin, SimplePixi5Plugin as default };

 

 

So in short my suggestion would be: Create a PixiPlugin per pixi-version if the pixi innerworkings change. In my opinion that's easier to use and doesn't need extra code to sniff the pixi version. It also doesn't need the PIXI-object or some workaround just to register the pixi version we already know. The PIXI object isn't always available when using bundlers like Webpack and why do extra work inside the plugin to detect the pixi version if we already know which PIXI version we are using, so we could pick the right pixiPlugin (4 or 5) directly. The propertyname at use in tweens could still be 'pixi' for both PixiPlugin4 as well as PixiPlugin5 and so on, only the innerworkings could be different (like using 'angle' instead of 'rotation' for Pixi v5).

 

 

  • Like 1
Link to comment
Share on other sites

19 hours ago, OSUblake said:

gsap.registerPlugin(SomePlugin, AnotherPlugin);

 

How will this be when different modules use the same plugin(s)?

 

So for example module A uses the PixiPlugin and calls gsap.registerPlugin('pixiPlugin') and module B (that doesn't know of the existence of module A) also uses the PixiPlugin and therefor calls gsap.registerPlugin('pixiPlugin') too.

 

Can we call registerPlugin() more than once to register the same plugin?

Link to comment
Share on other sites

On 9/7/2019 at 2:30 PM, OSUblake said:

So do this, and see if it works.


window.PIXI = {
  DisplayObject: DisplayObject
};

 

Yep, I guess it doesn't have to be the official PIXI object - just something that has DisplayObject, filters, VERSION, and Graphics properties that point to the corresponding values in PIXI. And you're welcome to try feeding that into PixiPlugin.registerPIXI() if you don't want to attach it to the window. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...