7

I'm trying to get CAEmitterLayers and CAEmitterCells to start their animation from somewhere in the middle of their parent's duration. Is this possible at all? I tried playing with the beginTime and timeOffset properties but I can't seem to get this working.

Added some code for posterity: (lets say I want the emitter to start at the 5th second)

    CAEmitterLayer *emitter = [CAEmitterLayer new];
    // emitter.beginTime = -5.0f; // I tried this
    // emitter.timeOffset = 5.0f; // I also tried this, with beginTime = 0.0, and with beginTime = AVCoreAnimationBeginTimeAtZero
    /* set some other CAEmitterLayer properties */

    CAEmitterCell *cell = [CAEmitterCell new];
    // cell.beginTime = -5.0f; // Then I saw that CAEmitterCell implements CAMediaTiming protocol so I tried this
    // cell.timeOffset = 5.0f; // and this
    /* set some other CAEmitterCell properties */

    emitter.emitterCells = @[cell];
    [viewLayer addSubLayer:emitter];

But still the animation starts from where the emitter generates the particles.

Edited again to explain what I'm trying to do:

Lets say I have a CAEmitterLayer that animates rain, so I setup the cells to do a "falling" animation that starts from the top of the screen. During the start of rendering, I don't want to start in a state that's "not raining yet". I want to start where the screen is already covered with rain.

John Estropia
  • 17,460
  • 4
  • 46
  • 50

1 Answers1

2

The beginTime isn't relative to now. You need to grab the current time relative to the current layer time space, which you can get by using the CACurrentMediaTime() function. So in your case, you'd do something like this:

emitter.beginTime = CACurrentMediaTime() + 5.f;
sudo rm -rf
  • 29,408
  • 19
  • 102
  • 161
  • To be honest, my superLayer is a `AVSynchronizedLayer` so my timing runs with an `AVPlayerLayer`, not `CACurrentMediaTime()`. But, I did try your method with a raw `UIView.layer` but it still doesn't behave the way I expect it to. I'm starting to think that emitters only handle timing that runs forward, not backward. – John Estropia Aug 21 '12 at 04:25
  • Oh ok, I think I explained it wrong. I don't want the emitter to start AFTER 5 seconds. I want the emitter to run 5 seconds EARLIER than the parent timing. I edited the question to include an example of what I want to do. – John Estropia Aug 21 '12 at 04:34
  • @erurainon: If I follow your question correctly, you want to have a negative offset, which really isn't possible, for obvious reasons. :) However, can't you just offset the parent instead? – sudo rm -rf Aug 21 '12 at 04:53
  • I tried that too, but to no effect. Theoretically, a positive `timeOffset` should be the one to do what I'm expecting, but it doesn't seem that way... – John Estropia Aug 21 '12 at 06:23
  • @erurainon: I guess I don't understand why you can't just set the emitter's beginTime to be 5 seconds later. Maybe I'm just not getting what you're trying to do. – sudo rm -rf Aug 21 '12 at 06:48
  • If I set the beginTime to 5, the rain won't start to fall until 5 seconds after. My objective is the opposite. I want the rain to start 5 seconds ahead. – John Estropia Aug 21 '12 at 07:43