Michael71

Animating KineticJS objects

  • 14 posts in this topic

14 posts in this topic

Hello, I'm trying to animate a rectangle created with KineticJS, however I keep getting "Uncaught TypeError: Cannot read property 'setX' of undefined"

 

the code is the following:

 

var scrub = new Kinetic.Rect({
 x: 0,
 y: 0,
 width: 4,
 height: 120,
 fill: '#ff3019',
 draggable: true,
 id:'scrub',
 name:'scrub',
 dragBoundFunc: function(pos) {
	 return {
	 x: pos.x,
	 y: this.getAbsolutePosition().y
	 }
 }
});
TimelineMax({paused:true});
 tl.insert(TweenMax.to(scrub,5,{css:{setX:500},onComplete:function(){
 console.log('to 500');
 }}));
tl.insert(TweenMax.to(scrub,5,{css:{setX:800},onComplete:function(){
 console.log('to 800');
 }}));

tl.play();

 

Do you guys have any idea why is this throwing an error?

 

Thanks in advance!

Share this post


Link to post
Share on other sites

Hi Michael,

 

I've used KineticJS a few times and was very happy with how it worked with GSAP.

 

Keep in mind when drawing to the canvas, you aren't using css props so you shouldn't need to wrap your props in a css Object try this instead:

 

 

 

var tl = new TimelineMax({paused:true});
tl.insert(TweenMax.to(scrub,5,{setX:500, onComplete:function(){
console.log('to 500');
}}));
tl.insert(TweenMax.to(scrub,5,{setX:800, onComplete:function(){
console.log('to 800');
}}));

 

 

ps. i got your recent PM, I've been sick lately so that's why I haven't been able to respond.

Share this post


Link to post
Share on other sites

I think you just forgot to tell KineticJS to draw() on each update, so the changes are made but you're not seeing them. Just add an onUpdate to your TimelineMax (and make sure you define the scope) like this:

 

var tl = new TimelineMax({paused:true, onUpdate:stage.draw, onUpdateScope:stage});

 

Does that help?

Share this post


Link to post
Share on other sites

Yes that did it, although I'm getting a bit of a delay before the animation starts and the labels don't display as they should, but I'm still looking into it.

 

Thanks for the help once again!

Share this post


Link to post
Share on other sites

Yes it seems that when I'm defining a timelineMax on a kineticJS canvas element all the labels fire at once instead of their desired interval. any help there?

Share this post


Link to post
Share on other sites

Do you have an updated fiddle that exhibits this behavior?

Share this post


Link to post
Share on other sites

Sure here it is : http://jsfiddle.net/7aQvP/95/

 

maybe I'm missing something in the timelineMax declaration. What I'm trying to achieve is to call the "callback" function at these specified times as the "playhead" moves at the same time.

Share this post


Link to post
Share on other sites

From what I'm seeing, this is expected behavior. Let me explain a few things:

  1. Labels don't actually take up any "space" on the timeline, but callbacks do. Callbacks are basically zero-duration tweens with an onComplete. Therefore, append() calls do factor in callbacks but not labels. In other words, if you have an empty timeline and then put a label at 100 and then append() a tween or callback, it'll be at the 0 position, not 100. If, on the other hand, you have an empty timeline and put a callback at 100 and then append() a tween or callback, it'll be positioned at 100.
  2. If you try inserting a tween/callback at a label that doesn't exist, that label will automatically be appended to the end of the timeline and then the tween/callback will be inserted there.
  3. When you use an alert() Javascript call, it doesn't stop time.

Your code placed 3 labels, "myLabel_1", "myLabel_3", and "myLabel_4" into the timeline at various times but then you tried adding a callback at "myLabel_2" which doesn't exist. Therefore, it was appended to the end, which at that point was 1 second into the timeline. That's where the callback for "myLabel_1" was located too.

 

So your code would cause the "myLabel_1" and "myLabel_2" callbacks to both get called at exactly 1 second into the timeline. Each of those caused alert() windows to be spawned and by the time you clicked the "okay" button to get rid of those, the timeline was most likely already past the 6-second spot in the timeline, so you'd see the "myLabel_3" alert() pop up right away. So it APPEARED as though all 3 callbacks were getting called immediately one-after-the-other but in reality only the myLabel_1 and myLabel_2 were (as they should).

 

Does that clear things up?

  • 1 person likes this

Share this post


Link to post
Share on other sites

I think I understand why the alerts pop out like they do, but shouldn't the playhead simultaneously be moving as the alerts pop-up? Since I align them at start?

The "odd" behavior that I see is that after all alerts go off, then the playhead starts moving.

 

Should I declare something different in the original TimelineMax declaration for this to happen?

I have an almost similar code in AS3 that works as intended that's why I'm getting confused here.

 

In AS3 I use "addLabel" and "addCallback" however instead of "append", does that make a difference?

Share this post


Link to post
Share on other sites

You put the tween AFTER all the callbacks. And I believe alert() windows block scripts on the page from progressing (or at least the visuals from updating), so you won't see anything moving until after you close the alert() window. However, that doesn't mean that time stops while the alert() window is open - it still allows time to proceed, but scripts don't execute. Therefore as soon as the alert() window closes, the timeline updates again and renders at the appropriate time. It might LOOK like things suddenly jump to mid-tween, but that's because it's supposed to according to the time that was lost during the alert().

 

See what I mean?

  • 1 person likes this

Share this post


Link to post
Share on other sites

I think Jack's points cover it nicely, but I'll try and step through it.

 

The difference in appending labels and callbacks means you haven't actually aligned everything at the start:

> append label1 with offset 1: label inserted at 1, tl.duration = 0

> append label3 with offset 6: label inserted at 6, tl.duration = 0

> append label4 with offset 10: label inserted at 10, tl.duration = 0

> add callback at label1: callback inserted at 1, tl.duration = 1

> add callback at label2: label created at 1, callback inserted at 1, tl.duration = 1

> add callback at label3: callback inserted at 6, tl.duration = 6

> append 15 second tween: tween inserted at 6, tl.duration = 21

 

Your tween won't be starting until after 6 seconds / your 3rd callback.

 

I think you'll see your 'expected' behaviour if you change tl.append(TweenMax.to... to tl.insert(TweenMax.to...

 

Also, because alerts block visual updates but don't stop time passing, I've updated your fiddle to use on-screen messages to show the callbacks.

  • 2 people like this

Share this post


Link to post
Share on other sites

Yes I see now what was wrong with my code. The key point was the difference between append and insert

 

I updated the fiddle to show what I was after. http://jsfiddle.net/7aQvP/98/

 

Thank you both very much for the help. It cleared some things greatly.

Share this post


Link to post
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.