ComponentKit/Core/CKAnimation.mm (104 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 "CKAnimation.h" using namespace CK; auto Animation::TimingCurve::fromCA(NSString *name) noexcept -> TimingCurve { return fromCA([CAMediaTimingFunction functionWithName:name]); } auto Animation::TimingCurve::fromCA(CAMediaTimingFunction *f) noexcept -> TimingCurve { auto p1 = ControlPoint{}; auto p2 = ControlPoint{}; [f getControlPointAtIndex:1 values:p1.data()]; [f getControlPointAtIndex:2 values:p2.data()]; return {p1, p2}; } auto Animation::TimingCurve::toCA() const -> CAMediaTimingFunction * { return [CAMediaTimingFunction functionWithControlPoints:_p1[0] :_p1[1] :_p2[0] :_p2[1]]; } auto Animation::SpringInitialBuilder::toCA() const -> CAAnimation * { auto const a = [CASpringAnimation animationWithKeyPath:_keyPath]; a.fromValue = _from; this->applyTimingTo(a); a.fillMode = kCAFillModeBackwards; this->applySpringTo(a); a.duration = a.settlingDuration; return a; } auto Animation::InitialBuilder::usingSpring() const -> SpringInitialBuilder { auto spring = SpringInitialBuilder{_from, _keyPath}; spring.delay = delay; spring.curve = curve; return spring; } auto Animation::InitialBuilder::toCA() const -> CAAnimation * { auto const a = [CABasicAnimation animationWithKeyPath:_keyPath]; a.fromValue = _from; this->applyTimingTo(a); a.fillMode = kCAFillModeBackwards; return a; } auto Animation::FinalBuilder::toCA() const -> CAAnimation * { auto const a = [CABasicAnimation animationWithKeyPath:_keyPath]; a.toValue = _to; this->applyTimingTo(a); a.fillMode = kCAFillModeForwards; a.removedOnCompletion = NO; return a; } auto Animation::SpringChangeBuilder::toCA() const -> CAAnimation * { auto const a = [CASpringAnimation animationWithKeyPath:_keyPath]; this->applyTimingTo(a); if (delay > 0) { a.fillMode = kCAFillModeBackwards; } this->applySpringTo(a); a.duration = a.settlingDuration; return a; } auto Animation::ChangeBuilder::usingSpring() const -> SpringChangeBuilder { auto spring = SpringChangeBuilder{_keyPath}; spring.delay = delay; spring.curve = curve; return spring; } auto Animation::ChangeBuilder::toCA() const -> CAAnimation * { auto const a = [CABasicAnimation animationWithKeyPath:_keyPath]; this->applyTimingTo(a); if (delay > 0) { a.fillMode = kCAFillModeBackwards; } return a; } static auto animatedValueAsId(CGFloat f) -> id { return @(f); } static auto animatedValueAsId(UIColor *c) -> id { return (id)c.CGColor; } auto Animation::alphaFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"opacity"}; } auto Animation::translationXFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"transform.translation.x"}; } auto Animation::translationYFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"transform.translation.y"}; } auto Animation::backgroundColorFrom(UIColor *from) -> InitialBuilder { return {animatedValueAsId(from), @"backgroundColor"}; } auto Animation::borderColorFrom(UIColor *from) -> InitialBuilder { return {animatedValueAsId(from), @"borderColor"}; } auto Animation::scaleXFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"transform.scale.x"}; } auto Animation::scaleYFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"transform.scale.y"}; } auto Animation::scaleFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"transform.scale"}; } auto Animation::rotationFrom(CGFloat from) -> InitialBuilder { return {animatedValueAsId(from), @"transform.rotation"}; } auto Animation::alphaTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"opacity"}; } auto Animation::translationXTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"transform.translation.x"}; } auto Animation::translationYTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"transform.translation.y"}; } auto Animation::backgroundColorTo(UIColor *to) -> FinalBuilder { return {animatedValueAsId(to), @"backgroundColor"}; } auto Animation::borderColorTo(UIColor *to) -> FinalBuilder { return {animatedValueAsId(to), @"borderColor"}; } auto Animation::scaleXTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"transform.scale.x"}; } auto Animation::scaleYTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"transform.scale.y"}; } auto Animation::scaleTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"transform.scale"}; } auto Animation::rotationTo(CGFloat to) -> FinalBuilder { return {animatedValueAsId(to), @"transform.rotation"}; } auto Animation::alpha() -> ChangeBuilder { return {@"opacity"}; } auto Animation::position() -> ChangeBuilder { return {@"position"}; }; auto Animation::backgroundColor() -> ChangeBuilder { return {@"backgroundColor"}; } auto Animation::borderColor() -> ChangeBuilder { return {@"borderColor"}; } auto Animation::rotation() -> ChangeBuilder { return {@"transform.rotation"}; }