Jump to content
GreenSock

daneiran

TweenMax bezier and Pixi

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

Has anyone been able to make a demo like this one: 

 

See the Pen Kajpu by GreenSock (@GreenSock) on CodePen

 

only using Pixi instead of Kinetic? We are using Pixi and can make an object follow the spline path, but it will not auto-rotate to actually align with the path no matter what we do. 

 

Any help would be greatly appreciated. 

Link to comment
Share on other sites

I haven't personally used Pixi, but I've heard great things about it. I glanced at the docs and it looks like the "rotation" property is supposed to be set in radians rather than degrees, so you'd need to do a custom autoRotate value:

autoRotate:["x","y","rotation",0,true]

Does that help? If not, could you describe what's happening exactly? Does it rotate at all? Can you whip together a simple codepen example so that we can see what's going on? http://forums.greensock.com/topic/9002-read-this-first-how-to-create-a-codepen-demo/

Link to comment
Share on other sites

We definitely tried true, and many other combinations, but no happiness with autorotation so far after several hours.  The best we can do is get it to follow the spline, but that looks strange for our animation without the autorotation capability.  Do you have any other ideas for us?  (Thanks ahead!!)

 

  var kzBgX = 172;
  var kzBgY = 25;

  TweenMax.to(kzRocket.position, 10, {
    bezier:{
      values:[
  {x:(kzBgX-30), y:(kzBgY+140)},
  {x:(kzBgX+215), y:(kzBgY+50)},
  {x:(kzBgX+388), y:(kzBgY+30)},
  {x:(kzBgX+493), y:(kzBgY+15)},
  {x:(kzBgX+528), y:(kzBgY-10)},
  {x:(kzBgX+453), y:(kzBgY-50)},
  {x:(kzBgX+443), y:(kzBgY+5)},
  {x:(kzBgX+473), y:(kzBgY+30)},
  {x:(kzBgX+503), y:(kzBgY+40)},
  {x:(kzBgX+570), y:(kzBgY+50)},
  {x:(kzBgX+830), y:(kzBgY+50)}
      ],
      autoRotate:["x","y","rotation",0,true]
  },
      repeat:-1,
      repeatDelay:3});
 

Link to comment
Share on other sites

Sorry, if it helps for completeness, this is kzRocket.  Just a sprite object made in the standard Pixi way out of a png:

 

  var kzBgX = 172;
  var kzBgY = 25;

  var texture1 = PIXI.Texture.fromImage("resources/rocket.png");
  var kzRocket = new PIXI.Sprite(texture1);
  kzRocket.position.x = kzBgX - 30;
  kzRocket.position.y = kzBgY + 140;
  this.stage.addChild(kzRocket);
 

It seems like for some reason autorotate is compatible with Kinetic but not Pixi?  This is our first project trying to use greensock.  We had committed to the Pixi renderer b/c of glowing reviews like you mentioned.  It seems like the above code should work, no?

Link to comment
Share on other sites

Hi,

 

What you could try is animate another element through the same bezier path, a transparent div, with absolute position, a z-index of 0 and visibility:hidden in order to not disrupt your layout. Set the autoRotate to true and set the autoRotate to false in your pixi element. Then using an onUpdate callback in the tween of the div element you can pass the element's rotation to your pixi sprite using the native pixi method to do that, something like this:

var testDiv = document.getElementById("dummy-div");

TweenMax.to(testDiv, time,
{
  bezier:
  {
    type:"soft",
    values:yourPath,
    autoRotate:true
  },
  onUpdate:updateFn
});

function updateFn()
{
  var elRotation = testDiv._gsTransform.rotation;
  
  yourPixiElement.rotation = elRotation * ( Math.PI / 180 );
}

Is not ideal but it might work, just keep in mind that the _gsTransform object returns the rotation in degrees and for what I read in the Pixi docs they use radians, that's why the math is included in the code.

 

Rodrigo.

Link to comment
Share on other sites

Although Rodrigo's solution is clever and certainly should work, you really shouldn't have to do do that. Ultimately GSAP is all about simply setting properties on your JavaScript objects many times per second. And the BezierPlugin allows you to define basically all those properties arbitrarily and you can even make it use radians, so I'm really unsure as to why you're having any trouble. It'd help A LOT if you could provide a simple codepen example. I apologize - I just don't have much time to throw at learning Pixi, setting a test project up, trying to recreate your scenario, etc. But if I could glance at a codepen that's already set up, it'd make it much faster/easier. Any chance you could provide that? 

Link to comment
Share on other sites

tried it and so far no dice.  same translating but no rotating. 

 

could it be something we're doing? (as this seems like it should work.) 

 

#1 concern we came up with is how we are defining "the div".  The suggestion as i understood was to add this seperate animation "item" (div) to run in parallel and basically grab its rotational properties to feed the actual pixi item we wish to rotate.  this seems ingenious and certainly plausible.  now just the devil in the details.  This how we defined the div rotation of which we capture in the (separate) TweenMax shown above:

 

 

<canvas id="our-canvas" width="960" height="500"><div id="dummy-div"></div><!-- <--KLUDGE --></canvas>

 

(We tried it a couple of ways outside of the canvas tag as well, with similar results of translate-only; no rotate.)

Link to comment
Share on other sites

We can do that.  Have a project meeting in 5 minutes, but I should have some time immediately afterwards to post something so far.  Haven't used codepen as yet.  The lines of pixi code are pretty minimal for the demo.  Probably 3-5.  Thanks so much for the quick replies, and no definitely don't go outside of the GSAP development.  I think it's close, just something not quiite aligning.  Will get back to you with that demo in another hour or three if meeting goes to plan.

Link to comment
Share on other sites

It looks like the problem is that you're targeting "kzRocket.position" instead of just "kzRocket". Apparently in Pixi, the "position" object is only for x/y values, so it does nothing to tween position.rotation. 

 

I tested your code and it seemed to work fine for me once I targeted the correct object. :)

Link to comment
Share on other sites

Could you explain the changes?  I made a codepen, finally.  Sorry it took some time--had to figure out how to code it up in there.  When I try to remove '.position' from line 55 of the JS thereon, autorotate still does not happen.  Was there more to it than that?  Thanks ahead.

Link to comment
Share on other sites

Hi,

 

You don't need to add the autoRotate configuration object to the Pixi element, just pass the simple boolean to the dummy div and then the update callback takes care of the rest:

TweenMax.to(kzRocket.position, tR, {
    bezier:{
      type:"soft",
      values:[
  {x:(kzBgX-30), y:(kzBgY+140)}, 
  {x:(kzBgX+215), y:(kzBgY+50)}, 
  {x:(kzBgX+388), y:(kzBgY+30)}, 
  {x:(kzBgX+493), y:(kzBgY+15)}, 
  {x:(kzBgX+528), y:(kzBgY-10)}, 
  {x:(kzBgX+453), y:(kzBgY-50)}, 
  {x:(kzBgX+443), y:(kzBgY+5)}, 
  {x:(kzBgX+473), y:(kzBgY+30)}, 
  {x:(kzBgX+503), y:(kzBgY+40)}, 
  {x:(kzBgX+570), y:(kzBgY+50)}, 
  {x:(kzBgX+830), y:(kzBgY+50)}
      ]
}, 
      repeat:-1,
      repeatDelay:tD});



  // KLUDGE TOP
  testDiv = document.getElementById("dummy-div");
TweenMax.to(testDiv, tR,
{
  bezier:
  {
    type:"soft",
      values:[
  {x:(kzBgX-30), y:(kzBgY+140)}, 
  {x:(kzBgX+215), y:(kzBgY+50)}, 
  {x:(kzBgX+388), y:(kzBgY+30)}, 
  {x:(kzBgX+493), y:(kzBgY+15)}, 
  {x:(kzBgX+528), y:(kzBgY-10)}, 
  {x:(kzBgX+453), y:(kzBgY-50)}, 
  {x:(kzBgX+443), y:(kzBgY+5)}, 
  {x:(kzBgX+473), y:(kzBgY+30)}, 
  {x:(kzBgX+503), y:(kzBgY+40)}, 
  {x:(kzBgX+570), y:(kzBgY+50)}, 
  {x:(kzBgX+830), y:(kzBgY+50)}
      ],
  autoRotate:true,
  },
  repeat:-1,
  repeatDelay:tD,
  onUpdate:updateRocketRotFn
});
  // KLUDGE END

You can make your code even more concise. Since you're applying the same tween values to both elements, you can add them to the same tween as an array:

// KLUDGE TOP
  testDiv = document.getElementById("dummy-div");
TweenMax.to([testDiv,kzRocket.position], tR,
{
  bezier:
  {
    type:"soft",
      values:[
  {x:(kzBgX-30), y:(kzBgY+140)}, 
  {x:(kzBgX+215), y:(kzBgY+50)}, 
  {x:(kzBgX+388), y:(kzBgY+30)}, 
  {x:(kzBgX+493), y:(kzBgY+15)}, 
  {x:(kzBgX+528), y:(kzBgY-10)}, 
  {x:(kzBgX+453), y:(kzBgY-50)}, 
  {x:(kzBgX+443), y:(kzBgY+5)}, 
  {x:(kzBgX+473), y:(kzBgY+30)}, 
  {x:(kzBgX+503), y:(kzBgY+40)}, 
  {x:(kzBgX+570), y:(kzBgY+50)}, 
  {x:(kzBgX+830), y:(kzBgY+50)}
      ],
  autoRotate:true,
  },
  repeat:-1,
  repeatDelay:tD,
  onUpdate:updateRocketRotFn
});
  // KLUDGE END

And Jack is right, passing the kzRocket.rotation to the autoRotate object should work but it doesn't. I played a little with the codepen, Jack but neither of the following codes made a difference:

autoRotate:["x","y","kzRocket.position.rotation", 0,true]

autoRotate:["x","y",kzRocket.position.rotation, 0,true]

autoRotate:["x","y","kzRocket.rotation", 0,true]

autoRotate:["x","y",kzRocket.rotation, 0,true]

Rodrigo.

Link to comment
Share on other sites

It looks like you're using an old version of PIXI that doesn't correctly apply x/y values that are set directly on the target. In other words:

//OLD
obj.position.x = 20;

//NEW
obj.x = 20;

I dropped in the newest version of PIXI and it seems to work fine: http://codepen.io/GreenSock/pen/fee31a0d2175dd8890573c4e40b12522

 

If you want to stick with the old version, you could still do that and simply animate the "position" object, apply the rotation to that, and then copy that rotation back to the raw object in an onUpdate, like this:

 

http://codepen.io/GreenSock/pen/160eef749d77c74a6283d1b47241a913

 

Does that clear things up? 

  • Like 1
Link to comment
Share on other sites

Jack, Rodrigo,

 

Thank you, thank you for your excellent suggestions!!  We were indeed using an outdated Pixi.  Would have gotten back sooner but there was a lot of refactoring to do today.  The solution of simply using the object itself (instead of object.position) was in fact the best solution in our case. 

 

Generally speakikng, it could help matters greatly if there were a consistent way to poll for version number of these JS libs to make it easier to understand which codebase(s) we are using.  With GSAP JS this hasn't come to the fore yet in development the same as it has a few times already for PixiJS, however it would be good if all these libs had a simple

version();

call that reported a number that ticks up (i.e. maintained together) with each build release.  That would put developers directly in touch with what they were using.  We could even poll this vn, perhaps even strategically, within the downstream use codes.  At any rate, one for the wish-list.

 

Thank you so much for the excellent support.  We are big fans for these exchanges that helped make our rocket animation better with the autorotate.  Go GSAP!!

Link to comment
Share on other sites

Yeah, I hear you regarding version numbers and the headaches involved. FYI, GSAP has that already:

console.log( TweenLite.version );
console.log( TweenMax.version ); 
...etc.

Let us know if you need anything else. Happy tweening!

  • Like 1
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.
×