facebookarchive / pop

An extensible iOS and OS X animation library, useful for physics-based interactions.
Other
19.66k stars 2.88k forks source link

Any way to know the intermediate status of an ongoing animation? #342

Closed puneetgoyal08 closed 7 years ago

puneetgoyal08 commented 7 years ago

Hi, Is there any intermediate status of an ongoing animation?

`
POPBasicAnimation *anim = [self.valuesImageView.layer pop_animationForKey:@"rotate"];

if (anim) { TDTLogInfo(@"current float value %f", [anim.toValue floatValue]); anim.toValue = @([anim.toValue floatValue] + ); anim.duration += 30; } else { anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerRotation]; anim.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.0f:0.63f:0.01f:1.0f]; anim.toValue = @(); anim.removedOnCompletion = YES; anim.duration = 30.0f; anim.additive = YES; } [self.valuesImageView.layer pop_addAnimation:anim forKey:@"rotate"]; `

I am doing something like this. But I want to know the current status if anim already exists, so that i can put a cap on some_random_value

grp commented 7 years ago

The best way to know the current status is to read the value of the animated property. In this case, you're using kPOPLayerRotation, so you could use [layer valueForKey:@"rotation"] to read the current rotation value.

puneetgoyal08 commented 7 years ago

@grp I saw another property which was not exposed though .. currentValue, I got by [anim valueForKey:@"currentValue"]. But its always at risk, if the internal implementation ever got changed. Is that possible?

grp commented 7 years ago

I wouldn't use the currentValue. Instead, read the property from the object the animation is added to. It should be the same value.

puneetgoyal08 commented 7 years ago

Yes it is, but i was trying to build a framework on top of it, which could use something generic. Anyways i can provide it a mapping. Thanks! :)

grp commented 7 years ago

Ah. You might be able to use the readBlock() from the animatable property to do it generically — something like animation.property.readBlock(object, values), although you'll need to handle boxing.

puneetgoyal08 commented 7 years ago

@grp Yeah, that exactly looks like something i need.

POPAnimatableProperty *prop =
      [POPAnimatableProperty propertyWithName:kPOPLayerRotation
                                  initializer:^(POPMutableAnimatableProperty *prop) {
                                    // read value
                                    prop.readBlock = ^(id obj, CGFloat values[]) {
                                      TDTLogInfo(@"obj is %@, value is %@", obj, @(values[0]));
                                    };
                                    prop.writeBlock = ^(id obj, const CGFloat values[]) {
                                      TDTLogInfo(@"obj is %@, value is %@", obj, @(values[0]));
                                    };
                                    prop.threshold = 0.1;
                                  }];

  anim.property = prop;

This is the code i wrote for testing, to just see if its hitting anything. Do I have to define anything else as well, to make sure the write/read blocks are called? Or does the anim is supposed to be of some specific class? When i went through the readme page, i couldnt find anything where it needed any extra param or anything right?

grp commented 7 years ago

The read blocks are called by Pop for custom properties; you would need to provide a custom name rather than a default one to use it. But what you need here isn't a custom property.

My suggestion is to invert the usual flow and call the read block yourself, including for the default properties, as Pop does internally.