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"}; }