Skip to content
This repository has been archived by the owner on Aug 30, 2023. It is now read-only.

Commit

Permalink
Add support for additively animating bounds. (#93)
Browse files Browse the repository at this point in the history
Closes #74
  • Loading branch information
jverkoey committed Dec 14, 2017
1 parent e260418 commit 32c78d4
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
4 changes: 1 addition & 3 deletions src/MDMAnimatableKeyPaths.h
Expand Up @@ -58,9 +58,7 @@ FOUNDATION_EXPORT MDMAnimatableKeyPath MDMKeyPathBackgroundColor NS_SWIFT_NAME(b
Equivalent UIView property: bounds
Equivalent CALayer property: bounds
Expected value type: CGRect or NSValue (containing a CGRect).
Additive animation supported: No.
TODO( https://github.com/material-motion/motion-animator-objc/issues/74 ):
Add support for additively animating CGRect types.
Additive animation supported: Yes.
*/
FOUNDATION_EXPORT MDMAnimatableKeyPath MDMKeyPathBounds NS_SWIFT_NAME(bounds);

Expand Down
42 changes: 42 additions & 0 deletions src/private/CABasicAnimation+MotionAnimator.m
Expand Up @@ -44,6 +44,15 @@ static BOOL IsCGSizeType(id someValue) {
return NO;
}

static BOOL IsCGRectType(id someValue) {
if ([someValue isKindOfClass:[NSValue class]]) {
NSValue *asValue = (NSValue *)someValue;
const char *objCType = @encode(CGRect);
return strncmp(asValue.objCType, objCType, strlen(objCType)) == 0;
}
return NO;
}

static BOOL IsCATransform3DType(id someValue) {
if ([someValue isKindOfClass:[NSValue class]]) {
NSValue *asValue = (NSValue *)someValue;
Expand Down Expand Up @@ -270,6 +279,39 @@ void MDMConfigureAnimation(CABasicAnimation *animation, MDMAnimationTraits * tra
}
}

} else if (IsCGRectType(animation.toValue)) {
CGRect from = [animation.fromValue CGRectValue];
CGRect to = [animation.toValue CGRectValue];
CGRect additiveDisplacement = CGRectMake(from.origin.x - to.origin.x,
from.origin.y - to.origin.y,
from.size.width - to.size.width,
from.size.height - to.size.height);

if (animation.additive) {
animation.fromValue = [NSValue valueWithCGRect:additiveDisplacement];
animation.toValue = [NSValue valueWithCGRect:CGRectZero];
}

if (isSpringAnimation) {
// Core Animation's velocity system is single dimensional, so we pick the dominant direction
// of movement and normalize accordingly.
CGFloat biggestDelta = additiveDisplacement.origin.x;
if (fabs(additiveDisplacement.origin.y) > fabs(biggestDelta)) {
biggestDelta = additiveDisplacement.origin.y;
}
if (fabs(additiveDisplacement.size.width) > fabs(biggestDelta)) {
biggestDelta = additiveDisplacement.size.width;
}
if (fabs(additiveDisplacement.size.height) > fabs(biggestDelta)) {
biggestDelta = additiveDisplacement.size.height;
}
CGFloat displacement = -biggestDelta;
CGFloat absoluteInitialVelocity = springTimingCurve.initialVelocity;
if (fabs(displacement) > 0.00001) {
springAnimation.initialVelocity = absoluteInitialVelocity / displacement;
}
}

} else if (IsCATransform3DType(animation.toValue)) {
CATransform3D from = [animation.fromValue CATransform3DValue];
CATransform3D to = [animation.toValue CATransform3DValue];
Expand Down

0 comments on commit 32c78d4

Please sign in to comment.