統計情報(30日間)


最新情報をツイート

人気の投稿

オレオレアニメーションエンジンの為の実装

このエントリーをはてなブックマークに追加

POPに触発されて作ったとのこと。UIControlに紐づくようなアニメーションコードを書くのにとても参考になる。このライブラリ自体はカテゴリとして CALayerなどに紐付けるようにできてる。

CHAnimation is a project used to demonstrate how to write your own animation engine, inspired by Facebook Pop, with only 600 lines of Objective-C you can understand.



利用はこんなイメージ
#import "CHAnimation.h"

CHAnimation *animation = [CHAnimation new];
animation.duration = 0.4;

animation.writeBlock = ^(id obj, id value) {
    button.center = [value CGPointValue];
};

animation.fromValue = [NSValue valueWithCGPoint:CGPointMake(70, 70)];
animation.toValue = [NSValue valueWithCGPoint:CGPointMake(170, 170)];

[button ch_addAnimation:animation forKey:@"animation"]; 


内部を見ると CHAnimation, CHAnimationState, CHAnimator の3つから構成されていて、CHAnimationがアニメーションの定義、CHAnimationStateがアニメーションの状態管理と実行、CHAnimatorがアニメーションの管理(複数紐付けできるので)となっている。

まずCHAnimatorの -init で CADisplayLinkに描画メソッドを登録しておく(初期は停止)。
- (id)init
{
    self = [super init];
    if (self) {
    
        _displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render)];
        _displayLink.paused = YES;
        [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
          :
任意のタイミングで paused =NO にすればアニメーションするわけだ。

アニメーションのレンダリングは CHAnimator の -renderTime: で制御する。


- (void)renderTime:(CFTimeInterval)time
{
    [CATransaction begin];
    [CATransaction setDisableActions:YES];
    
    NSMutableArray *doneAnimations = [NSMutableArray new];
    
    for (CHAnimatorItem *item in _list) {
        CHAnimationState *state = CHAnimationGetState(item.animation);
        
        if ([state startIfNeeded:item.animation atTime:time]) {
            [state applyAnimation:item.animation atTime:time];

            if ([state isDone]) {
               
                [doneAnimations addObject:item];
                        :

登録されているアニメーションを取り出して描画していく。この時直接 CHAnimationを呼ぶのではなくタイミング等を管理する CHAnimationStateが状態を管理しつつ描画を行う(-[CHAnimationState applyAnimation:]→この中で -[CHAnimation writeBlock]を呼び出す)。

Leave a Reply