Ember Animated - z-index

Hi All,

I’m using ember-animated and enjoying the way it “just works” in the way it handles animation. There is a small issue that I’m trying to solve related to z-index.

Currently I set z-index to be 1 which is fine if there is only a single animation, but less than ideal with multiple concurrent animations. I could use a counter in the controller for the z-index of the animation and increment it each time I trigger an animation, but I’d also like a way to reset the counter when there are no animations running (i.e. all current animations have completed).

So I’m interested to know (and I can’t find answers in the documentation on on the web):

  • Is there a way of detecting the number of (active) animations? …or
  • Is there a way of determining when an animation has completed?

In either case this would allow me to reset the z-index when there are no animations. It’s a shame I can’t upload a video, but here’s a screen shot.

Thanks,

Dave

Every time you change the data the old transition is interrupted and a new one begins, so there’s not really a total number of running transitions.

I’m assuming you’re using sentSprites or receivedSprites here to animate between the lists? In that case, I think it’s sufficient to increase the z-index of all sentSprites or receivedSprites, while leaving all other types unchanged. That will lift the items that are crossing between lists above the items that are only moving within lists.

Yes I’m using sentSprites. I’ve tried implementing a maxZIndex property on the controller/component, but how do I reference it from the generator function (custom transition)?

I’m receiving a console error:

Uncaught (in promise) TypeError: Cannot read property 'maxZIndex' of undefined

I’ve tried referencing this. maxZIndex and the legacy “getter” syntax.

If you want to access this from your custom transition, you’ll need to bind it. It’s the typical Javascript this problem – it doesn’t come along automatically.

Transition functions are values that can be passed around, they’re not really methods, so we don’t try to automatically bind their this.

You can do:

class extends Component {
  constructor(...args) {
    super(...args);
    this.transition = this.transition.bind(this);
  }
  * transition({ sentSprites })  {
  }
}

Thank you Ed - that solved the problem of accessing the properties and this is no doubt a technique that I’ll take advantage off in general. There appears to be an interesting side effect with the implementation…

If I slow down the animation speed and then setoff a bunch of transitions the “sentSprites” block within the transition is run for the most latest sprite transition, but also for all of those sprites that haven’t yet completed the transition (i.e. they are still in sentSprites).

*transition({ keptSprites, sentSprites}) {
    yield sentSprites.forEach(sprite => {
        // bring the moving sprite to the front
        sprite.applyStyles({
            'z-index': (this.maxZIndex++).toString()
        });

        console.log(this.maxZIndex);  // I can see the z-index is incremented again for all sprites in transition
        move(sprite);
    });

    keptSprites.forEach(move);
}; 

Is it possible to get the z-index of the sprite? It’s not in the CopiedCSS of the Initial/Final computed style.

P.S. How do I format my code in this forum nicely like you have?

You deliberately can’t read the CSS of a sprite from inside a transition. If you did, it would cause layout thrashing that can be very bad for performance. If you need to remember which z-index you’ve already assigned to each sprite, I’d put them into a WeakMap so you can store it yourself.

Use triple back-ticks. The forum supports Markdown.