ComponentKit/Core/CKComponentBoundsAnimation.mm (68 lines of code) (raw):

/* * Copyright (c) 2014-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. An additional grant * of patent rights can be found in the PATENTS file in the same directory. * */ #import "CKComponentBoundsAnimation.h" void CKComponentBoundsAnimationApply(const CKComponentBoundsAnimation &animation, void (^animations)(void), void (^completion)(BOOL finished)) { // Avoid capturing the unmanaged reference to animation auto const ac = animation.completion; auto const _completion = ^(BOOL finished){ if (auto c = ac) { c(); } if (auto c = completion) { c(finished); } }; if (animation.duration == 0) { [UIView performWithoutAnimation:animations]; _completion(YES); } else { [CATransaction begin]; [CATransaction setAnimationTimingFunction:animation.timingFunction]; if (animation.mode == CKComponentBoundsAnimationModeSpring) { [UIView animateWithDuration:animation.duration delay:animation.delay usingSpringWithDamping:animation.springDampingRatio initialSpringVelocity:animation.springInitialVelocity options:animation.options animations:animations completion:_completion]; } else { [UIView animateWithDuration:animation.duration delay:animation.delay options:animation.options animations:animations completion:_completion]; } [CATransaction commit]; } } static BOOL CAMediaTimingFunctionsAreEqual(CAMediaTimingFunction *t1, CAMediaTimingFunction *t2) { if (t1 == t2) { return YES; } const auto pointsAreEqualAtIndex = [&](size_t index) { float point1[2], point2[2]; [t1 getControlPointAtIndex:index values:point1]; [t2 getControlPointAtIndex:index values:point2]; return point1[0] == point2[0] && point1[1] == point2[1]; }; return pointsAreEqualAtIndex(0) && pointsAreEqualAtIndex(1) && pointsAreEqualAtIndex(2) && pointsAreEqualAtIndex(3); } auto operator ==(const CKComponentBoundsAnimation &lhs, const CKComponentBoundsAnimation &rhs) -> bool { auto const commonPropsAreEqual = lhs.duration == rhs.duration && lhs.delay == rhs.delay && lhs.mode == rhs.mode && lhs.options == rhs.options && CAMediaTimingFunctionsAreEqual(lhs.timingFunction, rhs.timingFunction); if (lhs.mode == CKComponentBoundsAnimationModeDefault) { return commonPropsAreEqual; } return commonPropsAreEqual && lhs.springDampingRatio == rhs.springDampingRatio && lhs.springInitialVelocity == rhs.springInitialVelocity; } auto operator !=(const CKComponentBoundsAnimation &lhs, const CKComponentBoundsAnimation &rhs) -> bool { return !(lhs == rhs); }