a9 손떨방

카테고리 없음 2020. 7. 31. 22:49

50mm, 1/20s, resized

Posted by Starlight Dancer

https://discussions.apple.com/thread/6567790?tstart=0



Posted by Starlight Dancer

CAKeyframeAnimation 사용하기


키프레임 애니메이션은 특정한 시간(키프레임) 객체가 가져야 값을 지정하고, 사이의 값을 보간(interpolation)하는 방법으로 구현하는 애니메이션입니다.

예를 들어 공이 떨어져서 튀어오르는 애니메이션을 구현하기 위해서, 공의 초기값, 바닥값, 튀어올랐을 때의 최대값, 다시 바닥에 떨어졌을 때의 값에 대해 각각 시간과 위치를 입력하고, 나머지의 값은 자동으로 계산되도록 하는 것입니다.


키프레임 애니메이션을 구현하기 위해 CAKeyframeAnimation 제공됩니다. 다음은 간단한 예제입니다.


- (void)keyframeAnimation

{

    CAKeyframeAnimation* ani = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];

    ani.duration = 0.5;

    NSArray* values = @[ [NSNumber numberWithFloat:160.0],

                         [NSNumber numberWithFloat:400.0],

                         [NSNumber numberWithFloat:320.0],

                         [NSNumber numberWithFloat:400.0]

                        ];

    NSArray* keyTimes = @[ [NSNumber numberWithFloat:0.0],

                           [NSNumber numberWithFloat:0.7],

                           [NSNumber numberWithFloat:0.85],

                           [NSNumber numberWithFloat:1.0]

                        ];

   

    ani.values = values;

    ani.keyTimes = keyTimes;

    [self.itemView.layer addAnimation:ani forKey:@"ani" didStart:nil didStop:^(BOOL finished) {

        self.itemView.layer.position = CGPointMake(self.itemView.layer.position.x, 400.0);

    }];

}


keyTimes 배열과 values 배열은 1:1 대응되며, keyTimes 시간축은 항상 0.0 ~ 1.0입니다.

예제는 간단한 바운스를 구현한 예제입니다. 보간법을 지정하지 않았을 경우에는 키프레임 사이의 값이 linear하기 때문에 위의 예제는 실행시키면 상당히 어색한 움직임을 보입니다.


보간법을 지정하기 위해서 몇가지 방법이 있는데, 그중에서 보편적인 keyTimes 이용해 보도록 하겠습니다.

앞서 CABasicAnimation에서 timingFunction 프로퍼티에 CAMediaTimingFunction 지정하여 애니메이션의 흐름을 조정하는 방법을 사용했습니다.

키프레임 애니메이션에서는 키프레임마다 이를 설정할 있도록 timingFunctions라는 프로퍼티를 제공합니다.

키프레임이 4개일 경우, 키프레임 사이를 잇는 역할을 하는 timingFunction 3개가 필요합니다. (n-1)

위의 예제에 timingFunctions 추가하여 조금 자연스러운 애니메이션을 만들어 보도록 하겠습니다.


- (void)keyframeAnimation

{

    CAKeyframeAnimation* ani = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];

    ani.duration = 0.5;

    NSArray* values = @[ [NSNumber numberWithFloat:160.0],

                         [NSNumber numberWithFloat:400.0],

                         [NSNumber numberWithFloat:320.0],

                         [NSNumber numberWithFloat:400.0]

                        ];

    NSArray* keyTimes = @[ [NSNumber numberWithFloat:0.0],

                           [NSNumber numberWithFloat:0.7],

                           [NSNumber numberWithFloat:0.85],

                           [NSNumber numberWithFloat:1.0]

                        ];

   

    NSArray* timingFunctions = @[

                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn],

                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut],

                                 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]

                                 ];

   

    ani.values = values;

    ani.keyTimes = keyTimes;

    ani.timingFunctions = timingFunctions;

    [self.itemView.layer addAnimation:ani forKey:@"ani" didStart:nil didStop:^(BOOL finished) {

        self.itemView.layer.position = CGPointMake(self.itemView.layer.position.x, 400.0);

    }];

}


애니메이션에 기본 제공되는 timing function 사용하여 조금 부드러운 애니메이션을 만들었습니다.

아까보다는 낫지만, 기본 함수는 곡선이 다소 완만하기 때문에 중력을 표현하기엔 아직 다소 부자연스럽습니다.

베지어 곡선을 직접 만들어서 지정해 보도록 하겠습니다.


- (void)keyframeAnimation2

{

    CAKeyframeAnimation* ani = [CAKeyframeAnimation animationWithKeyPath:@"position.y"];

    ani.duration = 0.5;

    NSArray* values = @[ [NSNumber numberWithFloat:160.0],

                         [NSNumber numberWithFloat:400.0],

                         [NSNumber numberWithFloat:320.0],

                         [NSNumber numberWithFloat:400.0]

                         ];

    NSArray* keyTimes = @[ [NSNumber numberWithFloat:0.0],

                           [NSNumber numberWithFloat:0.7],

                           [NSNumber numberWithFloat:0.85],

                           [NSNumber numberWithFloat:1.0]

                           ];

   

    NSArray* timingFunctions = @[

                                 [CAMediaTimingFunction functionWithControlPoints:0.5 :0 :1 :0.5],

                                 [CAMediaTimingFunction functionWithControlPoints:0 :0.5 :0.5 :1],

                                 [CAMediaTimingFunction functionWithControlPoints:0.5 :0 :1 :0.5]

                                 ];

   

    ani.values = values;

    ani.keyTimes = keyTimes;

    ani.timingFunctions = timingFunctions;

    [self.itemView.layer addAnimation:ani forKey:@"ani" didStart:nil didStop:^(BOOL finished) {

        self.itemView.layer.position = CGPointMake(self.itemView.layer.position.x, 400.0);

    }];

}


Control point 할당된 값의 곡선은 http://cubic-bezier.com에서 확인할 있습니다.

떨어지는 동안은 점점 빨라지도록, 올라가는 동안은 점점 느려지게 보이도록 곡선을 조정한 것입니다.


만약 좀더 물리법칙에 가까운 애니메이션을 만들고자 한다면 계산이 복잡해집니다.

티몬앱에는 TMAnimation이라는 클래스가 있습니다. CAKeyframeAnimation 꼼수를 써서 다양한 커브를 구현한 내용입니다.

TMAnimation 커브 계산식은 오픈 소스 게임 프레임워크인 Sparrow에서 가져온 것이므로, 문서를 참고하시면 됩니다.


http://doc.sparrow-framework.org/v2/Classes/SPTransitions.html


바운스 예제를 좀더 현실적으로 만들어 보겠습니다. 이번에는 객체가 여러번 튑니다.


- (void)tmonBounceAnimation

{

    TMAnimation* ani = [TMAnimation animationWithKeyPath:@"position.y" startValue:50.0 endValue:500.0 duration:2.0 evaluationBlock:TMAnimationEaseOutBounceBlock];

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


.. 코드가 너무 간단해져 버렸네요.;;

사실 TMAnimation 원리는 100개의 프레임을 갖는 CAKeyframeAnimation입니다.

따라서너무 자주 쓰시면 안됩니다


그리고 startValue endValue float밖에 안되는 것은구현자의 게으름 때문입니다.

이부분은 필요할 NSValue등을 넣을 있도록 수정해서 쓰시면 되겠습니다.



Evernote Data:

{"source":  "missing value", "created": "2014 5 28 수요일 오후 5:16:30", "modified": "2014 5 28 수요일 오후 6:03:59", "tags": "", "altitude": "48.0", "latitude": "37.51442024", "longitude": "127.1016053" }



Posted by Starlight Dancer

Core Animation 이용한 애니메이션


좀더 다양한 애니메이션 흐름을 만들기 위해서는 Core Animation(이하 CA) 필요합니다.

제가 아는 한도 내에서, CA 필요한 경우는 다음과 같습니다.


     1. 애니메이션의 Curve 조정하고 싶은 경우 ( : 바운스)

     2. CALayer 애니메이션 가능한 모든 프로퍼티를 사용하고 싶은 경우

     3. 외에 좀더 복잡한 애니메이션을 조직화하고 싶은 경우 (안해봄)


CA 기본 객체는 CALayer CAAnimation으로, CALayer 사용하는 법에 대해서는 앞서 알아본 있습니다.


CAAnimation 애니메이션을 표시하는 기본적인 추상 클래스입니다. 다음과 같은 상속 구조를 가집니다.

     CAAnimation : 기본 애니메이션 클래스

          CAPropertyAnimation : CALayer 속성을 조정하는 메소드들을 포함합니다.

               CABasicAnimation : 개의 interpolation (from, by, to) 통해 애니메이션 흐름을 조절하는 기본 애니메이션 객체입니다.

               CAKeyframeAnimation : keyframe 애니메이션을 위한 클래스입니다. 애니메이션 흐름을 보다 세밀하게 조정하기 위해 사용합니다.



CABasicAnimation 시작하기


layer 속성을 조정하는 간단한 애니메이션 코드를 만들어 보겠습니다.


- (void)layerAnimation1

{

    CABasicAnimation* ani = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];

    ani.duration = 3.0f;

    ani.beginTime = CACurrentMediaTime() + 2.0f;

    ani.fromValue = [NSNumber numberWithFloat:0.0];

    ani.toValue = [NSNumber numberWithFloat:50.0];

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


줄은 레이어의 cornerRadius 변경하는 애니메이션을 만드는 선언입니다.

duration UIView animation duration 같습니다. 애니메이션이 실행되는 시간입니다.

beginTime delay 해당합니다. 다만 그냥 숫자를 넣으면 안되고, 현재 시간을 의미하는 CACurrentMediaTime() 값에 더해야 합니다.

fromValue toValue 애니메이션의 시작값과 끝값을 의미하는데, 둘다 숫자가 아닌 객체를 인자로 사용합니다.

이렇게 하는 이유는, keyPath scalar 아닌 값들(CGPoint, CGSize, CGRect) 사용할 있도록 설계되었기 때문입니다.

마지막 줄에서는 만들어진 애니메이션 객체를 실행할 레이어에 더해줍니다.

이렇게 애니메이션을 실행하면 UIView Animation에서는 변경이 불가능했던 cornerRadius 변경하는 애니메이션을 있습니다.


여기서 한가지, UIView Animation과는 다른 점이 있는데, CA에서는 애니메이션이 끝나면 레이어의 속성을 원래 값으로 되돌린다는 것입니다.

만일 UIView Animation 같이, 애니메이션이 끝난 상태로 레이어의 값을 조정하고 싶다면, 애니메이션이 끝난 레이어의 값을 직접 최종값으로 세팅해야 합니다.

애니메이션의 시작과 끝을 통보받기 위해서는 다음과 같이 CAAnimation delegate 구현해야 합니다.


- (void)layerAnimationWithDelegate

{

    CABasicAnimation* ani = [CABasicAnimation animationWithKeyPath:@"cornerRadius"];

    ani.duration = 3.0f;

    ani.beginTime = CACurrentMediaTime() + 2.0f;

    ani.fromValue = [NSNumber numberWithFloat:0.0];

    ani.toValue = [NSNumber numberWithFloat:50.0];

    ani.delegate = self;

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag

{

    self.itemView.layer.cornerRadius = 50.0f;

}


이렇게 하면 애니메이션이 종료된 콜백을 통해 레이어의 값을 바꿀 있습니다.

하지만 방법은 하나의 객체에서 여러개의 애니메이션을 사용할 경우 코드가 복잡해지는 문제점을 안고 있습니다.

UIView 애니메이션처럼 block 이용해서 콜백을 받는 것이 좋겠지만 지원되지 않습니다.

따라서 이럴 흔히 사용하는 해법인 Associative Reference 사용하곤 합니다. 부분은 따로 알려드리도록 하겠습니다.


keyPath scalar값만 사용할 있는 것이 아니라고 위에 이야기했습니다. 이럴 경우 fromValue toValue NSNumber 아닌 NSValue 사용합니다.

레이어의 transform 속성을 조정하는 예제를 보겠습니다.


- (void)layerAnimationWithNSValue

{

    CABasicAnimation* ani = [CABasicAnimation animationWithKeyPath:@"transform"];

    ani.duration = 3.0f;

    CATransform3D startTransform = CATransform3DIdentity;

    CATransform3D endTransform = CATransform3DMakeTranslation(30, 30, 0);

    ani.fromValue = [NSValue valueWithCATransform3D:startTransform];

    ani.toValue = [NSValue valueWithCATransform3D:endTransform];

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


혹은 transform 일부의 값만 조정하고 싶을 수도 있습니다. 이런 문법도 사용이 가능합니다.


- (void)layerAnimationWithTransformEx

{

    CABasicAnimation* ani = [CABasicAnimation animationWithKeyPath:@"transform.translation.x"];

    ani.duration = 3.0f;

    ani.fromValue = [NSNumber numberWithFloat:0.0];

    ani.toValue = [NSNumber numberWithFloat:50.0];

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


이런 방식으로 조정 가능한 속성들에 대해서는 다음 링크를 참고하시면 됩니다.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreAnimation_guide/Key-ValueCodingExtensions/Key-ValueCodingExtensions.html



CAMediaTimingFunction & Bezier Curve


위에서 UIView에서 애니메이션이 움직이는 방법을 조정하는 Easing Function 대해 알아본 있습니다.

UIView Animation 매우 제한적인 Easing만을 제공하는데, CA에서는 보다 다양한 애니메이션을 사용할 있습니다.

이때 사용하는 것이 CAMediaTimingFunction입니다. 우선은 UIView Animation 같은 일을 하는 간단한 예제를 보겠습니다.


- (void)animationWithBasicMediaTimingFunction

{

    CABasicAnimation* ani = [CABasicAnimation animationWithKeyPath:@"position.x"];

    ani.duration = 3.0f;

    ani.fromValue = [NSNumber numberWithFloat:160.0];

    ani.toValue = [NSNumber numberWithFloat:280.0];

    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


이처럼 CAAnimation 객체에 timingFunction 적용함으로써, UIView Animation에서 사용했던 easing function CA에서도 사용할 있습니다.

다만 CAMediaTimingFunction에서는 기본 제공되는 함수 외에, control point 사용해서 애니메이션의 동작(curve) 조정하는 방법을 제공합니다.


여기에서 베지어 곡선이 등장합니다. 베지어 곡선은 컴퓨터 그래픽에서 곡선을 그리기 위해 사용하는 대중적인 방법입니다.

포토샵과 같은 그래픽 툴에서 곡선을 그릴때 나오는 모양이 바로 베지어 곡선입니다.

CA에서는 3 베지어 곡선(혹은 cubic bezier라고도 합니다) 사용해서 애니메이션의 커브를 조정할 있습니다.

3 베지어 곡선은 시작점과 끝점, 그리고 중간점 두개로 정의되는데, CA에서 시작점은 항상 0, 끝점은 항상 1이며, 나머지 두개의 중간점을 control point라고 합니다.


이부분은 원래 머리가 아프지만, 누군가가 여기 사용하라고 아주 아름다운 사이트를 만들어 주었습니다.

http://cubic-bezier.com


사이트에 방문해서, 빨간 점과 파란 점을 요리조리 움직여서 곡선의 모양을 정하고, 데모를 있습니다.

빨간 점과 파란 점을 움직일 변화하는 개의 숫자가 control point입니다. 숫자를 이용해서 애니메이션을 만들어 보겠습니다.


- (void)animationWithControlPoints

{

    CABasicAnimation* ani = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

    ani.duration = 3.0f;

    ani.fromValue = [NSNumber numberWithFloat:0.5];

    ani.toValue = [NSNumber numberWithFloat:1.0];

    ani.timingFunction = [CAMediaTimingFunction functionWithControlPoints:0.6 :0.22 :0.9 :1.76];

    [self.itemView.layer addAnimation:ani forKey:@"ani"];

}


약간 어설프긴 하지만, 일종의 바운스 애니메이션을 만들 있습니다.



CAAnimationGroup


여러가지 애니메이션을 동시에 실행하기 위해 CAAnimationGroup 사용할 있습니다.

CAAnimationGroup, 하나의 레이어에서 여러개의 속성을 동시에 애니메이션할 사용합니다.

이때 duration CAAnimationGroup 것을 따라갑니다. 하나의 그룹 안에 duration 애니메이션이 있다면, 해당 애니메이션은 group duration 끝나는 시점까지만 움직입니다.


- (void)animationWithAnimaionGroup

{

    CABasicAnimation* ani1 = [CABasicAnimation animationWithKeyPath:@"transform.scale"];

    ani1.duration = 3.0f;

    ani1.fromValue = [NSNumber numberWithFloat:0.5];

    ani1.toValue = [NSNumber numberWithFloat:1.0];

    CABasicAnimation* ani2 = [CABasicAnimation animationWithKeyPath:@"position.x"];

    ani2.duration = 10.0f;

    ani2.fromValue = [NSNumber numberWithFloat:160.0];

    ani2.toValue = [NSNumber numberWithFloat:300.0];

    CAAnimationGroup* aniGroup = [CAAnimationGroup animation];

    aniGroup.animations = @[ani1, ani2];

    aniGroup.duration = 3.0f;

    [self.itemView.layer addAnimation:aniGroup forKey:@"ani"];

}




Evernote Data:

{"source":  "missing value", "created": "2014 5 22 목요일 오후 4:21:51", "modified": "2014 5 26 월요일 오후 12:51:04", "tags": "", "altitude": "33.091815948486", "latitude": "37.506928499597", "longitude": "127.067404838655" }



Posted by Starlight Dancer

UIView Animation


가장 간단한 애니메이션 기법은 UIView 정적 메소드인 animationWithDuration 사용합니다.

iOS 7.0에서 추가된 새로운 애니메이션 메소드는 제외하고, 기본 애니메이션 문법은 다음과 같습니다.


[UIView animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations]

[UIView animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion]

[UIView animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion]


앞의 메소드는 3번째의 축약형이므로 마지막 것만 설명합니다.

duration 애니메이션이 재생되는 시간( 단위)입니다.

delay 애니메이션이 시작되기 전에 딜레이( 단위)입니다.

options 애니메이션에 들어가는 옵션들입니다. UIViewAnimationOptions 참고하세요.

animations 블록에서는 애니메이션이 일어날 속성들을 적어줍니다.

completion 애니메이션의 수행이 끝난 일어날 일들을 적어줍니다.

여기에 추가적으로 애니메이션 코드 중첩시켜 연속적인 변화를 있습니다.


다음은 간단한 예제입니다. itemView 2초간 y축으로 500까지 이동시킨 ,

0.5 후에 2초간 itemView 색상을 파랑으로 바꿉니다.

모든 애니메이션이 끝나면 itemView 속성들을 원래대로 되돌립니다.


    CGFloat y = self.itemView.y;

    UIColor* color = self.itemView.backgroundColor;

   

    [UIView animateWithDuration:2.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        self.itemView.y = 500;

    } completion:^(BOOL finished) {

        [UIView animateWithDuration:2.0 delay:0.5 options:UIViewAnimationOptionCurveEaseInOut animations:^{

            self.itemView.backgroundColor = [UIColor blueColor];

        } completion:^(BOOL finished) {

            self.itemView.y = y;

            self.itemView.backgroundColor = color;

        }];

    }];



Easing Functions


UIViewAnimationOptions 항목 다음 가지가 있습니다.

   UIViewAnimationOptionCurveEaseInOut            = 0 << 16,

   UIViewAnimationOptionCurveEaseIn               = 1 << 16,

   UIViewAnimationOptionCurveEaseOut              = 2 << 16,

   UIViewAnimationOptionCurveLinear               = 3 << 16,

Easing 시작값과 끝값으로 이루어지는 애니메이션의 중간 흐름을 조절합니다.

EaseIn 느리게 시작해서 점점 빨라지는 흐름이며, EaseOut 빠르게 시작해서 점점 느려지는 흐름입니다.

EaseInOut 느리게 시작해서 점점 빨라졌다가, 애니메이션의 종반부에선 다시 느려지면서 끝납니다.

Linear 애니메이션의 흐름 속도가 일정합니다

보통 가장 자연스러운 흐름은 EaseInOut이지만 보여주고 싶은 애니메이션에 따라 바뀔 있습니다.

4가지밖에 안되는 Easing Function UIView Animation 주요 제한점 하나입니다.



Animation Properties


애니메이션 가능한 UIView 프로퍼티는 다음과 같습니다.


  @property frame

  @property bounds

  @property center

  @property transform

  @property alpha

  @property backgroundColor


* UIView transform 속성은 CGAffineTransform으로, 2차원 변환만을 지원합니다.

아래 설명할 CALayer transform과는 다른 구조체입니다.


외에, 뷰와 연결된 layer 애니메이션 가능한 프로퍼티 역시 모두 사용할 있습니다.

티몬앱에서 layer 속성을 바꾸는 방법으로 애니메이션을 구현한 경우가 있습니다.

레이어를 사용하면 다음과 같은 애니메이션이 가능합니다.


  The size and position of the layer

  The center point used when performing transformations

  Transformations to the layer or its sublayers in 3D space

  The addition or removal of a layer from the layer hierarchy

  The layer’s Z-order relative to other sibling layers

  The layer’s shadow

  The layer’s border (including whether the layer’s corners are rounded)

  The portion of the layer that stretches during resizing operations

  The layer’s opacity

  The clipping behavior for sublayers that lie outside the layer’s bounds

  The current contents of the layer

  The rasterization behavior of the layer



CALayer 사용하기


앞에서 알아본 같이, UIView 애니메이션 속성은 제한적인 비해 layer 사용하면 다양한 애니메이션을 사용할 있습니다.

레이어는 UIView.layer 속성으로 접근할 있으며, CALayer 타입입니다.

CALayer UIView 요소 그리기 담당하는 클래스이며, UIView 노출된 보다 풍부한 기능을 가지고 있습니다.


iOS에서 UIView CALayer 1:1 대응하며 하나의 속성을 바꾸면 다른쪽의 속성도 바뀝니다.

이러한 구현을 Layer-Backed View라고 합니다. OS X에서는 Layer-Hosting View라는 것도 있으며, 경우 구현이 다르므로

검색할 유의하시기 바랍니다.


CALayer 이용할 때는 한가지 문제가 있는데, 원래 CALayer 애니메이션은 Core Animation 일부이므로,

[UIView animatedXX] 이용할 경우 정상적으로 애니메이션 되지 않는 속성이 많다는 것입니다.

이부분은 뒤에 Core Animation 이용하는 부분에서 다루며, 우선 UIView 애니메이션에서 사용가능한 CATransform3D 설명합니다.


CALayer에서 애니메이션 가능한 프로퍼티 목록을 다음 링크에서 있습니다.

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/CoreAnimation_guide/AnimatableProperties/AnimatableProperties.html



CATransform3D 사용하기


UIView CALayer 둘다 transform속성을 가지고 있지만, UIView transform과는 달리,

CALayer transform 속성은 3D 변환이 가능한 CATransform3D형이며, 4x4 행렬을 의미하는 구조체입니다.


3D변환 행렬에 대한 기본적인 내용은 다음을 참고하세요.

http://blog.naver.com/ojh6t3k/20194968081


행렬을 이용해서 수행할 있는 기본 변환은 회전(rotate), 이동(translation), 크기조정(scale) 세가지입니다.

세가지를 혼합해서 좀더 다양한 애니메이션을 만들게 됩니다.


기본 transform 속성의 값은 4x4 단위행렬입니다. 단위행렬은 CATransform3DIdentity 액세스할 있습니다.

CATransform3DMakeXXX 함수를 이용하면 변환행렬을 만들 있습니다. 다음 코드는 z축으로 30도를 회전시키는 행렬을 만들어 적용하는 애니메이션입니다.

(angle 음수인 경우 회전방향이 반대가 됩니다.)


    [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        CATransform3D rotateX = CATransform3DMakeRotation(M_PI / 6, 1.0, 0, 0);

        self.itemView.layer.transform = rotateX;

    } completion:nil];


여러개의 변환을 동시에 하기 위해서는, 하나의 변환에 다른 변환을 더합니다. CATransform3DXXX 함수를 사용하면 됩니다.

아래는 2 확대와 이동을 동시에 적용시킨 애니메이션입니다.


- (void)scaleAndTranslate3D

{

    [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        CATransform3D scaleX = CATransform3DMakeScale(2.0, 2.0, 2.0);

        CATransform3D scaleAndTranslateX = CATransform3DTranslate(scaleX, 100.0, 0, 0);

        self.itemView.layer.transform = scaleAndTranslateX;

    } completion:^(BOOL finished) {

        self.itemView.layer.transform = CATransform3DIdentity;

    }];

}


3D 애니메이션에서 빼놓을 없는 것이 하나 있는데, 원근법입니다.

원근법이 정의되지 않으면 개체가 멀어지거나 가까워지는 모습을 제대로 표현할 수가 없습니다.

아래의 예제는 객체를 60 회전시키는 예제이지만, 원근이 표현되지 않았기 때문에 회전이 아니라 짜부라지는 것처럼 보입니다.


- (void)rotateWithoutPerspective

{

    CATransform3D transform = CATransform3DMakeRotation(M_PI / 3, 0.5, 0, 0);

    [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        self.itemView.layer.transform = transform;

    } completion:nil];

}


객체에 원근감을 주는 변환의 계산은 어렵지만, 결론은 단순합니다.

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreAnimation_guide/AdvancedAnimationTricks/AdvancedAnimationTricks.html#//apple_ref/doc/uid/TP40004514-CH8-SW13


페이지의 하단에 “Adding Perspective to Your Animations” 항목에서 변환에 원근감을 주는 방법을 설명하고 있습니다.

예제에서는 CATransform3D m34 세팅한 다음 sublayerTransform 넣는 방법을 사용하지만,

변환을 수행할 CATransform3D m34 해당 내용처럼 들어있기만 하면 됩니다.

아래 예제에서 850 눈의 위치이며, 숫자를 크게 하면 원근도 커집니다.


- (void)rotateWithPerspective

{

    CATransform3D transform = CATransform3DIdentity;

    transform.m34 = - 1.0f / 850;

    transform = CATransform3DRotate(transform, M_PI / 3, 0, 0.5f, 0);

    [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        self.itemView.layer.transform = transform;

    } completion:nil];

}


CALayer anchorPoint 사용하기


CALayer에는 UIView 없는 중요한 속성 두가지가 있습니다.

하나는 position, 하나는 anchorPoint이며, CALayer 위치를 잡는 것은 두가지 프로퍼티입니다.

position layer 위치를 표현하는데, UIView position frame 좌측 최상단 점인데 비해,

layer에서는 position 기본적으로 layer 중점입니다. position 정확하게 layer 내의 어디를 의미하는지

결정하는 것이 anchorPoint이며, 기본값이 (0.5, 0.5)입니다


layer 회전시킬 경우 anchorPoint 중점이 되므로 값이 중요합니다.

anchorPoint 변경하면 그에 맞추어 layer 이동하게 되는데, 보통은 이를 의도하지 않기 때문에

anchorPoint 인해 이동하는 레이어를 원래 위치로 돌려놓는 코드를 작성하게 됩니다

티몬 앱에서 코드는 [UIView setAnchorPoint:], UIView+Helper 카테고리에 정의되어 있습니다.


다음 예제는 나머지 부분에서 위의 rotateWithPerspective 동일하지만, anchorPoint 오른쪽 끝으로 설정한 것입니다.


- (void)rotateWithAnchorPoint

{

    [self.itemView setAnchorPoint:CGPointMake(1.0f, 0.5f)];

    CATransform3D transform = CATransform3DIdentity;

    transform.m34 = - 1.0f / 850;

    transform = CATransform3DRotate(transform, M_PI / 3, 0, 0.5f, 0);

    [UIView animateWithDuration:3.0 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{

        self.itemView.layer.transform = transform;

    } completion:nil];

}


Evernote Data:

{"source":  "missing value", "created": "2014 3 17 월요일 오후 5:39:11", "modified": "2014 5 22 목요일 오후 4:24:43", "tags": "", "altitude": "missing value", "latitude": "missing value", "longitude": "missing value" }



Posted by Starlight Dancer



Posted by Starlight Dancer

원래 안하는 줄 알고 있었는데...

HD Native 라인이 썬더볼트를 지원한다고 해서 얼른 찾아보니 오... 지원한다.


그래서 처음 맥프로 발표 때 절망적이었던 썬더볼트 라인업을 다시 찾아봤다.

PCIe 에서만 되던 대부분의 다채널 인터페이스들이 대부분 썬더볼트를 지원하더라.


RME야 USB 3.0을 진작부터 지원했고, 당분간 썬더볼트로 올 생각 없어 보이니 제끼고,

큼직한 회사들은 대부분 거의 최상위 라인업에 썬더볼트 디바이스가 올라와 있다.

다만 웃기게도 MOTU는 썬더볼트 도입의 최전선에서 828x를 신나게 팔아먹더니,

HD192에 썬더볼트를 올리는 데에는 실패한 모양이다.

(혹은 몇대 팔리지도 않는 장비라 개발하기 귀찮은지도 모른다)


Lynx같은 경우는 좀 부랴부랴 나온 느낌이 있다. PCI 카드를 꽂는 섀시를 제공한다.

뭐 어쩌면 이바닥에서는 그게 맞는 걸지도 모른다...

기존 제품에 대한 사용자들의 선호도가 워낙 큰지라. 


혹시나 하고 헤일로나 오르페우스 같은 것도 찾아봤지만... 역시 이분들은 꿋꿋하게..

USB2.0과 FW800인터페이스를 고집하고 계시더라. ㅋㅋ


여튼 애플의 패기 덕분인지 왠만큼 이름있는 회사들은 대부분 업그레이드가 된 듯.

PCIe를 써가면서까지 개기던 게을러터진 업계가 변화했다는 건 상당한 희소식.

조만간 홈레코딩 장비도 썬더볼트 달고 나오고 뭐 그런 기대를 해본다.

어렵게 습득한 기술일 테니 울궈 먹으려 들겠지. USB 2.0으로도 진짜 얼마나 해먹은 건가.


근데 정작 이걸 다 찾아보게 만든 HD Native의 썬더볼트 발표는 재작년이었다는게 함정.

헐.











Posted by Starlight Dancer

www2014

카테고리 없음 2014. 4. 11. 12:31

필드에 있는 사람에게 학회는 계륵이랄까

딱히 도움될 것 같지 않은데 그렇다고 외면했다간 

그야말로 어메이징한 신기술에 언제 뒤통수를 맞을지 모른다.

그러니 결국 필요한건 예의주시.

내 티켓이 아니다 으하핫..


괜찮아보였던 세션들..






Posted by Starlight Dancer

GA-H87N-WiFi

카테고리 없음 2014. 4. 11. 11:15

기가바이트의 ITX 보드.

17x17cm라는 작은 사이즈의 비결은 PCIe 슬롯이 하나만 빼고 전부 삭제된 것이다.

나는 PCIe에 뭘 꽂아본 일이 단 한번도 없다.

M.2 SSD가 시판되면 모를까...

그래서 이걸 사고 실버스톤의 미니케이스(FT-03 mini)를 샀다.

그래픽카드 때문에 생각보다는 좀 커졌지만, 여튼 보드는 딱 좋은 듯.



Posted by Starlight Dancer

음질 차이?

카테고리 없음 2014. 3. 12. 04:54

나는 DAC간의 음질 차이를 구분해 낼 수 있다는 것이
정말 가능한지 매우 의심스럽다.

누군가 자기 시력이 1024.0이라고 하면 믿을 수 있겠어?

Posted by Starlight Dancer
123

Starlight Dancer

달력

태그목록