Jump to content


  • Posts

  • Joined

  • Last visited

Everything posted by mmontoya

  1. This is great! Thanks for sharing. I think the bottleneck in my example was due to having to calculate the positions of all those particles in 3D space on the CPU and then doing a projection into screen space. Time to roll up my sleeves and learn about vertex/fragment shaders!
  2. In fact, in the end, I animated the explosion in Houdini and rendered it as a sprite sheet which I can vary with hue shift and scale. This gave me the most artistic control and best performance. (I attached a frame from the sequence, below). Great resource, BTW! I was not aware of shadertoy - lots of great examples to pick apart!
  3. In the end, the requirements for this changed - it longer needs to be scrubbable, just interactive, which simplifies things a bit, as I no longer need to tie the animation's progress to a playhead. Nevertheless, it seems plausible to drive the "update" function, which receives a heartbeat from GSAP's ticker, with a progress event instead, and then scale that by whatever the total length of the desired animation might be. I could then set the rockets to fire at predetermined moments in time and call that function from within a GSAP timeline. Here's a Codepen of what I worked out: https://codepen.io/montoyland/pen/mdPbdQX?editors=0010 I would love to be able to turn each explosion fragment itself into an emitter so each fragment leaves behind a trail of particles, but this was already bogging down my machine (in fact, I'm currently limiting the firing of the rockets to one at a time), and if we multiply each fragment by 1000 or so particles, this could easily get out of control fairly fast and result in millions of particles in just a few seconds. As all I really need is to convey the sense of fireworks - it can remain stylized, so this is good enough for now.
  4. Nice! (Great minds think alike! ) As mentioned above, I will use PIXI particles and will likely calculate my own physics, as all I really need is to scale acceleration as a function of time (no need for bouncing or collisions). My thought was to calculate the coordinates in 3D space and then do the math to project onto a 2D plane in order to have that nice Sideshow Bob, volumetric look:
  5. My thought was to use parametric equations so that the motion of the particles was a function of t. For example, if I wanted to do some simple ballistics, I could move a particle on the screen in a parabolic trajectory defined by: If I use the scrubber as the input to t, I could then scale t (total length) by whatever amount I find most reasonable. The only precondition, as you suggest, is that the duration be known at the start, but this is fine, as I can tweak the total length until the timing seems appropriate. So for example, using a sin or modulus function, with an input of t, I can set a firework to go off every n seconds and then drive the explosion through parametric equations (I am working with PIXI, so I will likely use PIXI particles). In theory, what I have in mind is feasible - I will post back with a Codepen when I have a working POC.
  6. I am looking to have the best of both worlds: I would like to procedurally create an animation of exploding fireworks, but I would also like that animation to be scrubbable via GSAP. I'm not quite sure how to tackle this. My intuition tells me that I need to parameterize the procedural animation as a function of time, so that I can then use GPSAPs "progress" to drive the whole thing. Does anyone know of any examples I might examine that uses such an approach?
  7. @OSUblake Thanks! That is very useful! I confess I wasn't aware that the index of the currently iterated element was available within the tween! @ZachSaucier Another excellent tip! I had no idea the relative syntax was also available on properties! Thanks! That makes for very compact code! Thank you both for making learning GSAP such an enjoyable experience - It's been a real pleasure learning GSAP! (In no small part due to the excellent community on here). Now that I have discovered it, I don't know what I'd do without it!
  8. Nevermind... I basically answered my own question even as I wrote it. For others coming across this edge case, everything works as you might expect because, in the end, we are using plain javascript, so the solution was quite simple: I simply created my own custom stagger using the map function for an array of Sprites, setting up each tween by taking on the "<0.3" syntax at the end of each one! You gotta love GSAP because it just works! I know I do! Here's a code snippet with my solution, in case anyone encounters this: shipSprites.map((ship, index) => { scene.timeline.to( ship, { pixi: { positionX: shipsArray[index].destX, positionY: shipsArray[index].destY, }, duration: 10, ease: 'power3.out', }, '<0.3' ); }); In my code, the "scene" constant is implemented as a class that contains a reference to a gsap timeline, so I can tack on animation, extending it as I go... the key, really, is the use of the '<0.3' position parameter to offset each animation from the previous one.
  9. Hello Folks, I have a specific case which I am not sure how to handle: I have an array of PIXI Sprites that I would like to stagger to another set of X, Y coordinates. While they each have specific start coordinates assigned to them, their destination coordinates are defined by an offset from a target destination point. The effect that I want is for the sprites to tween in formation - think of a squadron of planes, or a vee of geese, flying together in formation. What I need to accomplish this, then, would be not unlike the map function where I can iterate through an array of objects, setting their tween properties dynamically, without hard-coding the destination coordinates in tween config object. Is there a built-in function within the stagger property, that would give me access to the current instance so I can access its destination coordinates? I was thinking I might be able to hack the stagger's function(index, target, list), but how can I set a tween within a function that is out of scope of the timeline's config object?
  10. Hmmm, digging through the forums is not ideal - one has to sift through many comments (many of them outdated) to piece together a viable solution. Given it's a special attribute of a Tween, I would expect to find it mentioned there, in the Docs. Perhaps it can be a added to the list of "properties" under .vars ? I see it as an extremely powerful property, particularly useful to tween transformation matrices for 3D (but also 2D), giving low-level access to the coordinate space - much too important to have it tucked away in relative obscurity! Here is a Codepen, showing how I am using the endArray property to create the beginnings of an ink-bleeding effect by Tweening PIXI's ColorMatrix filter: https://codepen.io/montoyland/pen/pojMjdL?editors=0010
  11. Thanks so much Blake! That works beautifully, and is exactly what I was looking for! Where is that documented? I scoured the GSAP 3 docs and was unable to find anything regarding this built-in plugin. My temporary solution was to tween the individual cells in the matrix that needed to change as they converged to identity, but this is obviously a much more elegant solution! BTW - if you need help providing examples in order to expand the documentation, I'm happy to provide a Codepen. 🙂
  12. In order to achieve the above effect, I need to tween the values of a colorMatrix filter, which are defined as an array of 20 numbers. This post would suggest that it is possible to tween an array: But, given it's from 2013, I am unable to find a GSAP 3 example. How might I go about this? The obvious, doesn't seem to be working for me: let tl = gsap.timeline() .to(colorMatrix, { duration: 3, ease: 'none', matrix: identMatrix }) /** * Where identMatrix is defined as: * const identMatrix = [ 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, ]; */ Many thanks!
  13. Thanks Zack! Diving a little deeper, I discovered it's really no big deal to simply iterate through an array of text, turn it into a PIXI Text Graphics object, then convert that into a Sprite. This then opens up the possibility of using an animated mask in addition to blur filters and blending modes, which will be useful to achieve the look I am going for: an ink bleeding into paper effect, applied to text loaded at runtime, from a JSON file.
  14. Given the TextPlugin (or it's sister plugin, SplitText) is meant to work on the DOM, I'm assuming it won't work inside a PIXI project since all its output lives entirely within a <canvas> tag. 😪 That being said, I'm wondering if anyone knows of a work-around?
  15. My pleasure! Looking forward to the release! 🙂
  16. I am working on a Typescript PIXI project, using GreenSock as my animation engine, and in setting up a function to jump to a specific label in a Timeline, my IDE complained that the play() function only accepts numbers... A check of the Typescript definitions shows that Timeline inherits from Animation, and sure enough, in the interface for the Animation class, play() is defined as: play(from?: number | null, supressEvents?: boolean): this; I'm assuming, that if I update the definition to: play(from?: number | string | null, supressEvents?: boolean): this; ...things should work as expected and the timeline will play from a defined label. I haven't yet verified that this works as it should, but I will report back if I overlooked something and this fails.
  17. Hahaha! Glad to see my instincts were right about extending the Sprite Class... 🙂 I suppose I'm always a bit wary of hacking someone else's code because experience has shown me that, unless you really understand its internals quite well, you're likely going to code yourself into a mess when things start to break (which they always do, as per Murphy's Law) and this can suck untold hours of your time in order to solve, which can be quite nerve-wracking when you've got a deadline! I am using Typescript , so it's not as easy as adding the extra properties to the prototype object as you might do with vanilla JavaScript. What I did, was to extend PIXI's Sprite class like this: export class SpritePlus extends PIXI.Sprite { private _active: boolean; private _title: string; private _XYScale: number; constructor(sprite: PIXI.Sprite) { super(sprite); } get active(): boolean { return this._active; } set active(value: boolean) { this._active = value; } get title(): string { return this._title; } set title(value: string) { this._title = value; } set XYScale(value: number) { this.scale.x = number; this.scale.y = number; this._XYScale = number; } get XYScale():number { return this._XYScale; } } This now allows me to proportionally drive the scale with a single value, since I am always scaling equally in x and y. Since this is for a UI, the "active" property allows me to identify which element has been clicked, so that I can Tween it to it's "active state". The "title" property, I use to display the currently selected chapter that is then passed along to a "SceneManager" class. As for the registerPIXI method - even though it's not in the type definitions, as the method is indeed in the class, the Typescript transpiler doesn't throw an error, so while I don't have code-hinting, it still works when I build the project. 🙂 Thank you for all your hard work! I am greatly enjoying digging through the GSAP docs! Today it's the GSAP Timeline Class, tomorrow... the world! 😉
  18. Thank you so much, Zach! That was totally it! (I didn't realize the values needed to be wrapped in a pixi object 🙄). You're my green-caped hero! 🙂 Thank you, also, for taking the time to provide a CodePen - I have learned so much from them! Really loving this community! 😍
  19. Thank you, Zach! A console.log does indeed show it is of type PIXI.Sprite (so the scale: {x: number, y: number}) property does exists on it. Sprite {_events: Events, _eventsCount: 0, tempDisplayObjectParent: null, transform: Transform, alpha: 1, …} If I am unable to get to the bottom of this, is there an alternative way to Tween the properties of an array of Sprites? This currently works, but I would also like to animate the scale.x and scale.y properties together with the alpha: // this.navigationDots is an array of PIXI.Sprites gsap.to(this.navigationDots, { alpha: 0, scaleX: 0, //<-- this fails stagger: { amount: duration, from: 'end', }, });
  20. Hi Blake, I'm new to GSAP and really enjoying the power that comes with it! I am working on a PIXI typescript/webpack project as well and in tweening the scaleX and scaleY properties, I am getting the same error as @spassvogel, despite having imported the packages in the manner you suggested above: import * as PIXI from 'pixi.js'; import { gsap } from 'gsap'; import { PixiPlugin } from 'gsap/PixiPlugin'; gsap.registerPlugin(PixiPlugin); PixiPlugin.registerPIXI(PIXI); The error I am getting is: Invalid property scaleX set to 0 Missing plugin? gsap.registerPlugin() I am calling the Tween like this in my code: gsap.to(this.connectorLine, { scaleX: 0, alpha: 0, duration: 0.5, }); (Where this.connectorLine is a PIXI.Sprite) I have been puzzling over this over the better part of two days, and I am at a loss as to what the issue might be. One thing that strikes me as fishy is that despite using Typescript, my code editor (VS Code), doesn't provide any code hinting for the imported PixiPlugin and shows no method called registerPIXI in the namespace. (In fact, it shows no methods or member variables at all). Importing the PixiPlugin as: import * as PIXIPlugin from 'gsap/PixiPlugin"; and import PixiPlugin from 'gsap/PixiPlugin'; // Default export also lead to the same error... My next course of action is to hack the Sprite class by extending it in order to define scale as a single variable, (since I am scaling equally in x and y, and therefore don't need it to be a point value), but hacks are ugly 🤢 and I'd rather just get the plugin working since that is what it was designed to do! Thank you for any insights you may be able to provide! Cheers!