1

I have a animated CAEmitterLayer with CAEmitterCell and the animation runs well with

 fireEmitter = (CAEmitterLayer*)self.layer; 
    fireEmitter.emitterPosition = CGPointMake(50, 50);
    fireEmitter.emitterSize = CGSizeMake(10, 10);

    CAEmitterCell* fire = [CAEmitterCell emitterCell];
    ...
    [fire setName:@"fire"];

CAKeyframeAnimation *anim = [CAKeyframeAnimation animationWithKeyPath:@"emitterPosition"];
    anim.path = theBezierPath.CGPath;
    anim.calculationMode = kCAAnimationCubicPaced;
    anim.repeatCount = HUGE_VALF;
    anim.duration = 12.0;
    [self.layer addAnimation:anim forKey:@"fire"];

my bezier path is closed and forms a "8" out of four position points. with my timerFunction I try to get the position of the CAEmitterLayer every second. for that I use

-(CGPoint)getEmitterPosition
{
    return fireEmitter.emitterPosition;
}

in the emitter class and

CGPoint emitterPosition = [self.ParticleEmitterView getEmitterPosition];
NSLog(@"%f / %f", emitterPosition.y, emitterPosition.y);

from the timer function.

But when the animation is running the console spits out the same positio every call allthough the emitter is running over the screen.

why is that and how could I get the emitter position of an animated CAEmitterLayer/Cell?

headkit
  • 3,307
  • 4
  • 53
  • 99

1 Answers1

2

Have you tried querying the CAEmitterLayer's presentationLayer property and asking the resulting CALayer for its position? The presentation layer should give you access to the properties of the layer as they appear on the screen during the animation, while the emitter layer will give you the properties as they will be at the end of all current animations.

This is due to the model-view separation inherent in Core Animation's rendering architecture.

warrenm
  • 31,094
  • 6
  • 92
  • 116
  • sounds promissing. thank you. I try to understand and use that - as new as I am to objective-c... by the way: when I change the emitter position with touchesMoved and `-(void)setEmitterPositionToPoint: (CGPoint)p { //change the emitter's position fireEmitter.emitterPosition = p; }` everything works fine and I get the right position traced out. – headkit Jun 04 '12 at 17:52
  • I would expect that. You'll want to keep setting properties directly on your emitter layer; it's just that the presentation layer gives you a way to read back properties as they actually appear during animations. – warrenm Jun 04 '12 at 17:57
  • I now tried to return the position of the representationLayer via `CALayer *fireEmitterLayer = fireEmitter.presentationLayer; return fireEmitterLayer.position;` but the problem is still the same. – headkit Jun 04 '12 at 18:05
  • hm - it could'nt be impossible to track the position of animated layers, right? – headkit Jun 06 '12 at 10:39
  • maybe it's because of the initialization: `fireEmitter = (CAEmitterLayer*)self.layer;`? – headkit Jun 06 '12 at 13:56
  • the main differences I see is that I overwrite the layerClass:`+ (Class) layerClass { //configure the UIView to have emitter layer return [CAEmitterLayer class]; }` and init with `fireEmitter = (CAEmitterLayer*)self.layer;` – headkit Jun 06 '12 at 14:52
  • or maybe the problem is that I create the emitter from inside the view, not the viewController? – headkit Jun 06 '12 at 14:59
  • I changed some settings and now it works fine! thank you for your demo code. that helped a lot! – headkit Jun 06 '12 at 15:09
  • unfortunately this change of code broke some other funktionality of my app... :-( – headkit Jun 06 '12 at 17:22
  • could you bring your code together with the 'draw with fire' functionality to follow the touch input data - stopping the path animation when touched first time, then following the fingers touch? – headkit Jun 06 '12 at 18:20
  • the problem now is that the particle trail is way beyond the touch position, looks like it is delayed by something. – headkit Jun 07 '12 at 10:49
  • opened a new thread here: http://stackoverflow.com/questions/10930668/touches-moved-caemitterlayer-delayed-in-dinstance-after-touch-point – headkit Jun 07 '12 at 11:13