| Index: ios/chrome/browser/ui/animation_util.mm
|
| diff --git a/ios/chrome/browser/ui/animation_util.mm b/ios/chrome/browser/ui/animation_util.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..1878c3e7709240f1422a4bf076c56ab74db7e329
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/animation_util.mm
|
| @@ -0,0 +1,94 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "ios/chrome/browser/ui/animation_util.h"
|
| +
|
| +#include <algorithm>
|
| +#include <cmath>
|
| +
|
| +#include "ios/chrome/browser/ui/reversed_animation.h"
|
| +
|
| +CAAnimation* FrameAnimationMake(CALayer* layer,
|
| + CGRect beginFrame,
|
| + CGRect endFrame) {
|
| + CGRect beginBounds = {CGPointZero, beginFrame.size};
|
| + CGRect endBounds = {CGPointZero, endFrame.size};
|
| + CABasicAnimation* boundsAnimation =
|
| + [CABasicAnimation animationWithKeyPath:@"bounds"];
|
| + boundsAnimation.fromValue = [NSValue valueWithCGRect:beginBounds];
|
| + boundsAnimation.toValue = [NSValue valueWithCGRect:endBounds];
|
| + boundsAnimation.removedOnCompletion = NO;
|
| + boundsAnimation.fillMode = kCAFillModeBoth;
|
| + CGPoint beginPosition = CGPointMake(
|
| + beginFrame.origin.x + layer.anchorPoint.x * beginBounds.size.width,
|
| + beginFrame.origin.y + layer.anchorPoint.y * beginBounds.size.height);
|
| + CGPoint endPosition = CGPointMake(
|
| + endFrame.origin.x + layer.anchorPoint.x * endBounds.size.width,
|
| + endFrame.origin.y + layer.anchorPoint.y * endBounds.size.height);
|
| + CABasicAnimation* positionAnimation =
|
| + [CABasicAnimation animationWithKeyPath:@"position"];
|
| + positionAnimation.fromValue = [NSValue valueWithCGPoint:beginPosition];
|
| + positionAnimation.toValue = [NSValue valueWithCGPoint:endPosition];
|
| + positionAnimation.removedOnCompletion = NO;
|
| + positionAnimation.fillMode = kCAFillModeBoth;
|
| + return AnimationGroupMake(@[ boundsAnimation, positionAnimation ]);
|
| +}
|
| +
|
| +CAAnimation* OpacityAnimationMake(CGFloat beginOpacity, CGFloat endOpacity) {
|
| + CABasicAnimation* opacityAnimation =
|
| + [CABasicAnimation animationWithKeyPath:@"opacity"];
|
| + opacityAnimation.fromValue = @(beginOpacity);
|
| + opacityAnimation.toValue = @(endOpacity);
|
| + opacityAnimation.fillMode = kCAFillModeBoth;
|
| + opacityAnimation.removedOnCompletion = NO;
|
| + return opacityAnimation;
|
| +}
|
| +
|
| +CAAnimation* AnimationGroupMake(NSArray* animations) {
|
| + CAAnimationGroup* animationGroup = [CAAnimationGroup animation];
|
| + animationGroup.animations = animations;
|
| + CFTimeInterval duration = 0.0;
|
| + for (CAAnimation* animation in animations)
|
| + duration = std::max(duration, animation.beginTime + animation.duration);
|
| + animationGroup.duration = duration;
|
| + animationGroup.fillMode = kCAFillModeBoth;
|
| + animationGroup.removedOnCompletion = NO;
|
| + return animationGroup;
|
| +}
|
| +
|
| +CAAnimation* DelayedAnimationMake(CAAnimation* animation,
|
| + CFTimeInterval delay) {
|
| + CAAnimation* delayedAnimation = [[animation copy] autorelease];
|
| + if (delayedAnimation) {
|
| + delayedAnimation.beginTime = delay;
|
| + delayedAnimation = AnimationGroupMake(@[ delayedAnimation ]);
|
| + }
|
| + return delayedAnimation;
|
| +}
|
| +
|
| +CABasicAnimation* FindAnimationForKeyPath(NSString* keyPath,
|
| + CAAnimation* animation) {
|
| + __block CABasicAnimation* animationForKeyPath = nil;
|
| + if ([animation isKindOfClass:[CABasicAnimation class]]) {
|
| + CABasicAnimation* basicAnimation =
|
| + static_cast<CABasicAnimation*>(animation);
|
| + if ([basicAnimation.keyPath isEqualToString:keyPath])
|
| + animationForKeyPath = basicAnimation;
|
| + } else if ([animation isKindOfClass:[CAAnimationGroup class]]) {
|
| + CAAnimationGroup* animationGroup =
|
| + static_cast<CAAnimationGroup*>(animation);
|
| + [animationGroup.animations
|
| + enumerateObjectsUsingBlock:^(CAAnimation* subAnimation, NSUInteger idx,
|
| + BOOL* stop) {
|
| + animationForKeyPath = FindAnimationForKeyPath(keyPath, subAnimation);
|
| + *stop = animationForKeyPath != nil;
|
| + }];
|
| + }
|
| + return animationForKeyPath;
|
| +}
|
| +
|
| +void RemoveAnimationForKeyFromLayers(NSString* key, NSArray* layers) {
|
| + for (CALayer* layer in layers)
|
| + [layer removeAnimationForKey:key];
|
| +}
|
|
|