|  | // Copyright 2016 The Chromium Authors | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #import "ios/chrome/common/material_timing.h" | 
|  |  | 
|  | namespace { | 
|  |  | 
|  | UIViewAnimationOptions AnimationOptionsForceLinearTiming( | 
|  | UIViewAnimationOptions options) { | 
|  | // Remove any non-linear timing options from `options`. They should be | 
|  | // ignored. | 
|  | options &= | 
|  | ~(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionCurveEaseIn | | 
|  | UIViewAnimationOptionCurveEaseOut); | 
|  | // Since default is EaseInOut, ensure linear is specified instead so the outer | 
|  | // timing function works as expected. | 
|  | options |= UIViewAnimationOptionCurveLinear; | 
|  | return options; | 
|  | } | 
|  |  | 
|  | // Constant to slow down animations during development. | 
|  | // Since iOS Simulator's "Debug > Slow Animations" doesn't apply to | 
|  | // CAAnimations, modify this multiplier here in code to run with slower/faster | 
|  | // Material animations. | 
|  | const NSTimeInterval kSlowAnimationModifier = 1; | 
|  |  | 
|  | }  // namespace | 
|  |  | 
|  | const CGFloat kMaterialDuration0 = 0 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration1 = 0.25 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration2 = 0.1 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration3 = 0.35 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration4 = 0.05 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration5 = 0.5 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration6 = 0.15 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration7 = 0.4 * kSlowAnimationModifier; | 
|  | const CGFloat kMaterialDuration8 = 0.07 * kSlowAnimationModifier; | 
|  |  | 
|  | CAMediaTimingFunction* MaterialTransformCurve2() { | 
|  | return | 
|  | [[CAMediaTimingFunction alloc] initWithControlPoints: | 
|  | 0.0f:0.84f:0.13f:0.99f]; | 
|  | } | 
|  |  | 
|  | CAMediaTimingFunction* MaterialTimingFunction(MaterialCurve curve) { | 
|  | switch (curve) { | 
|  | case MaterialCurveEaseInOut: | 
|  | // This curve is slow both at the beginning and end. | 
|  | // Visualization of curve  http://cubic-bezier.com/#.4,0,.2,1 | 
|  | return | 
|  | [[CAMediaTimingFunction alloc] initWithControlPoints: | 
|  | 0.4f:0.0f:0.2f:1.0f]; | 
|  | case MaterialCurveEaseOut: | 
|  | // This curve is slow at the end. | 
|  | // Visualization of curve  http://cubic-bezier.com/#0,0,.2,1 | 
|  | return | 
|  | [[CAMediaTimingFunction alloc] initWithControlPoints: | 
|  | 0.0f:0.0f:0.2f:1.0f]; | 
|  | case MaterialCurveEaseIn: | 
|  | // This curve is slow at the beginning. | 
|  | // Visualization of curve  http://cubic-bezier.com/#.4,0,1,1 | 
|  | return | 
|  | [[CAMediaTimingFunction alloc] initWithControlPoints: | 
|  | 0.4f:0.0f:1.0f:1.0f]; | 
|  | case MaterialCurveLinear: | 
|  | // This curve is linear. | 
|  | return | 
|  | [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; | 
|  | } | 
|  | } | 
|  |  | 
|  | @implementation UIView (CrMaterialAnimations) | 
|  |  | 
|  | + (void)cr_animateWithDuration:(NSTimeInterval)duration | 
|  | delay:(NSTimeInterval)delay | 
|  | materialCurve:(MaterialCurve)materialCurve | 
|  | options:(UIViewAnimationOptions)options | 
|  | animations:(void (^)(void))animations | 
|  | completion:(void (^)(BOOL finished))completion { | 
|  | [CATransaction begin]; | 
|  | [CATransaction | 
|  | setAnimationTimingFunction:MaterialTimingFunction(materialCurve)]; | 
|  | [UIView animateWithDuration:duration | 
|  | delay:delay | 
|  | options:AnimationOptionsForceLinearTiming(options) | 
|  | animations:animations | 
|  | completion:completion]; | 
|  | [CATransaction commit]; | 
|  | } | 
|  |  | 
|  | @end |