Archive

Posts Tagged ‘애니메이션’

개발뉴스 : 5월 8일 (2013)

– CSS 애니메이션을 이용해서 페이지 전환을 보여주는 모음 : http://goo.gl/0J3ir
Page transition collection.

– CSS3를 이용한 30개의 버튼 예제들. : http://goo.gl/nBsSk
30개의 CSS3 버튼들

iOS에서 애니메이션을 사용해 보자. (Core Animation)

최근에 Core Animation에 대해서 숙지하는 시간을 가졌습니다. 단순히 컨트롤이나 간단한 이미지에 대한 애니메이션 기능이라는 것은 알고 있었지만, 나중에 필요할 때에 찾아서 하면 되겠지라고 생각하고 있었는데, 마침 시간이 좀 있어서 정리를 해 보았습니다.
내용을 보면서 느낀 점은 Core Animation의 기능을 만드는 것은 마치 프리젠테이션 툴(파워포인트, 키노트 등)에서 오브젝트 애니메이션을 만드는 것과 비슷하다는 생각을 했습니다. 오브젝트를 움직이는 것도 중요하지만 잘 만들어진 애니메이션은 지나치지 않으면서도 꼭 필요한 곳에 적절하게 사용되는 것이 중요할 거라 생각되네요.

그럼 지금부터 간단한 설명과 효과에 대한 소스코드를 공유해 보려 합니다.

Core Animation을 이용하기 위한 기본적인 클래스는 ‘CAAnimation’ 입니다.. 그리고, CAAnimation에서 파생된 클래스가 아래와 같습니다.

  • CABasicAnimation:기본적인 애니메이션.(CAPPropertyAnimation의 파생클래스)
  • CAKeyframeAnimation:키프레임 애니메이션.(CAPPropertyAnimation의 파생클래스)
  • CATransition:레이어 전체에 대한 전환 효과.
  • CAAnimationGroup:여러 애니메이션을 같이 실행.

Core Animation classes and protocol

1. CABasicAnimation
CABasicAnimation은 레이어(CALayer)에 대해서 기본 애니메이션과 싱글 키프레임 애니메이션을 제공합니다.
아래 몇가지 프로퍼티를 가지고 있습니다.

  • fromValue: 애니메이션의 시작값
  • byValue: 애니메이션의 중간값
  • toValue: 애니메이션의 끝값

그럼 예제 소스를 하나 만들어 보겠습니다. 본 문서에서 예제들은 모두 뷰컨트롤러의 적당한 위치(viewDidLoad 등…)에 아래 소스를 넣어주면 됩니다.


    /* 움직이기 위한 대상 레이어를 만듭니다. */
    CALayer *layer1 = [CALayer layer];
    layer1.bounds = CGRectMake(0, 0, 40, 40);
    layer1.position = CGPointMake(0, 160);
    layer1.cornerRadius = 20;
    layer1.backgroundColor = [UIColor blackColor].CGColor;
    [self.view.layer addSublayer:layer1]; // 만든 레이어를 뷰 레이어에 올립니다.
    
    /* 이동할 위치 지정 */
    CGPoint pStart = CGPointMake(0, 160);
    CGPoint pEnd = CGPointMake(160,0);
    
    /* 애니메이션 작성 */
    CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath:@"position"];
    ani.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
    ani.fromValue = [NSValue valueWithCGPoint:pStart];
    ani.toValue = [NSValue valueWithCGPoint:pEnd];
    
    ani.repeatCount = HUGE_VAL;
    ani.duration = 10.0;
    [layer1 addAnimation:ani forKey:@"position"]; // 애니메이션을 원하는 레이어에 설정합니다.

위 소스를 통해 간단한 애니메이션을 구현할 수 있습니다. 검정색 원이 왼쪽 아래에서 오른쪽 위로 올라오는 것을 볼 수 있습니다. 위 소스의 애니메이션 작성 부분에서 아직 설명하지 않은 것은 세가지가 있습니다. timingFunction, repeatCount 그리고 duration 입니다. repeatCount와 duration은 이름과 같이 몇번 반복할 것인지와 애니메이션이 일어나는 시간을 설정하는 것 입니다.
timingFunction은 애니메이션이 일어나는 타이밍을 설정합니다. 타이밍 설정은 아래 네가지를 이용하여 설정할 수 있습니다.

  • kCAMediaTimingFunctionLinear : 일정한 속도로 재생
  • kCAMediaTimingFunctionEaseIn : 처음에 천천히 시작
  • kCAMediaTimingFunctionEaseOut : 마지막에 천천히 종료
  • kCAMediaTimingFunctionEaseInEaseOut : 천천히 시작하고 마지막에 다시 천천히 종료

이제 간단하게 객체를 이동하는 수준의 애니메이션을 작성할 수 있습니다.
이동 이외에도 Animation KeyPath의 동작은 아래와 같은 것도 있습니다.

2. CAKeyframeAnimation
키프레임 애니메이션을 만들어줍니다. 풀어서 얘기하면 정형적이지 않은 여러곳을 이동하는 프레임을 CGPathRef를 이용하여 설정하고, 그 위치를 특정 레이어가 이동하는 것 입니다.
기본적으로 사용하는 프로퍼티는 path, rotationMode가 있습니다.

간단한 예제를 보겠습니다.


    /* 움직이기 위한 대상 레이어를 만듭니다. */
    CALayer *layer1 = [CALayer layer];
    layer1.bounds = CGRectMake(0, 0, 20, 20);
    layer1.position = CGPointMake(200, 200);
    layer1.cornerRadius = 10;
    layer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:layer1]; // 만든 레이어를 뷰 레이어에 올립니다.
    
    /* 이동할 위치 지정 */
    CGMutablePathRef path1 = CGPathCreateMutable();
    CGPathMoveToPoint(path1,NULL,layer1.position.x, layer1.position.y);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 200);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x + 150, layer1.position.y + 150);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 0);
    
    /* 애니메이션 작성 */
    CAKeyframeAnimation *moveAni1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    moveAni1.path = path1;
    moveAni1.rotationMode = kCAAnimationRotateAuto;
    moveAni1.duration = 5.0;
    [layer1 addAnimation:moveAni1 forKey:@"position"]; // 애니메이션을 원하는 레이어에 설정합니다.

fromValue, toValue를 여러 포인트를 지정하는 path로 변경하고, 방향이 바뀌는 것에 대응하는 rotationMode를 제외하면 이전에 기본 애니메이션과 큰 차이는 없습니다.

3. CATransition
레이어가 전환되는 것을 처리하는 애니메이션 클래스입니다.
기본적으로 사용하는 프로퍼티는 아래와 같습니다.

  • type : 전환 애니메이션 종류.
  • subtype : 전화 애니메이션 방향.
  • duration : 애니메이션 시간.

간단한 예제를 통해 알아 보겠습니다.


    /* 전환 레이어 생성 */
    CALayer *layer4 = [CALayer layer];
    layer4.bounds = CGRectMake(0, 0, 320, 480);
    layer4.position = CGPointMake(0, 0);
    layer4.anchorPoint = CGPointMake(0, 0);
    layer4.backgroundColor = [UIColor blueColor].CGColor;
    [self.view.layer addSublayer:layer4];

    /* 전환 애니메이션 생성 */
    CATransition *transition = [CATransition animation];
    transition.type = kCATransitionReveal;
    transition.subtype = kCATransitionFromTop;
    transition.duration = 2.0;
    transition.delegate = self;
    [layer4 addAnimation:transition forKey:nil];

type에 설정되는 속성은 네가지입니다.

  • kCATransitionFade : 레이어를 바로 표시
  • kCATransitionMoveIn : subtype에 설정된 방향으로 진행하며 나타남. 이전에 있던 레이어 위로 나타남
  • kCATransitionPush : subtype에 설정된 방향으로 진행하며 나타남. 이전에 있던 레이어를 밀어냄
  • kCATransitionReveal : 희미한 상태에서 서서히 나타냄

subtype에 설정되는 속성은 네가지가 있습니다.

  • kCATransitionFromRight : 오른쪽 방향에서 들어옴.
  • kCATransitionFromLeft : 왼쪽 방향에서 들어옴.
  • kCATransitionFromTop : 아래에서 위로 올라옴. (왜? 테스트 결과 그렇게 됨.)
  • kCATransitionFromBottom : 위에서 아래로 내려옴.??

4. CAAnimationGroup
여러 애니메이션을 동시에 실행하는 경우 사용합니다. 예를 들면, 사진을 삭제하면 작아지면서 쓰레기통으로 이동하는 것에서 CABasicAnimation을 통해 작아지면서, CAKeyframeAnimation을 통해 이동하는 것으로 처리가 가능합니다. 마지막에 쓰레기통이 흔들리는 것은 Delegate설정을 한 후에 animationDidStop에서 처리해 주면 됩니다.
역시, 예제를 통해 알아보겠습니다.


    /* 움직이기 위한 대상 레이어를 만듭니다. */
    CALayer *layer1 = [CALayer layer];
    layer1.bounds = CGRectMake(0, 0, 20, 20);
    layer1.position = CGPointMake(200, 200);
    layer1.cornerRadius = 10;
    layer1.backgroundColor = [UIColor redColor].CGColor;
    [self.view.layer addSublayer:layer1]; // 만든 레이어를 뷰 레이어에 올립니다.
    
    /* 이동할 위치 지정 */
    CGMutablePathRef path1 = CGPathCreateMutable();
    CGPathMoveToPoint(path1,NULL,layer1.position.x, layer1.position.y);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 150);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x + 100, layer1.position.y + 100);
    CGPathAddLineToPoint(path1, NULL, layer1.position.x, layer1.position.y + 0);
    
    /* 이동 애니메이션 작성 */
    CAKeyframeAnimation *moveAni1 = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    moveAni1.path = path1;
    moveAni1.rotationMode = kCAAnimationRotateAuto;
    moveAni1.duration = 5.0;
    
    /* 스케일 애니메이션 작성 */
    CABasicAnimation *scalAni1 = [CABasicAnimation animationWithKeyPath:@"transform"];
    scalAni1.fromValue = [NSValue valueWithCATransform3D:CATransform3DIdentity];
    scalAni1.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeScale(0.1, 0.1, 1.0)];
    scalAni1.duration = 5.0;
    
    /* 투명 애니메이션 작성 */
    CABasicAnimation *opacityAni1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
    opacityAni1.fromValue = [NSNumber numberWithFloat:1.0];
    opacityAni1.toValue = [NSNumber numberWithFloat:0.1];
    opacityAni1.duration = 5.0;
    
    /* 애니메이션 그룹 작성 */
    CAAnimationGroup *group = [CAAnimationGroup animation];
    group.animations = [NSArray arrayWithObjects:moveAni1, scalAni1, opacityAni1, nil];
    group.duration = 5.0;
    
    [layer1 addAnimation:group forKey:nil]; //레이어에 그룹애니메이션 적용

그룹 애니메이션은 animations속성에 NSArray타입의 여러 애니메이션을 적용해 주는 것 만으로 애니메이션 동작이 가능합니다.

이상 CAAnimation의 기본적인 동작에 대해서 알아보았습니다. 간단한 앱내의 컨트롤들의 효과는 가능해 보이며, 재미있는 앱을 만들어 내는데 양념 역할을 충분히 할 수 있을 거라 생각합니다.
하지만, 처음에도 언급했던 것 처럼 지나친 애니메이션 사용은 사용자에게 피로감을 줄 수 있으니 잘 기획되어서 사용 해야겠습니다.

긴글 읽어주셔서 감사합니다.

추)
본문을 보시고, 코드 실행이 안되신다는 분들이 있습니다.
아마도 프레임워크 추가와 헤더 import에 대한 언급이 없어서 그런거라 판단됩니다. 그래서 간단한 이미지를 몇가지 첨부하겠습니다.
1. 프로젝트에 QuartzCore.framework 추가

2. 소스코드 추가 부분에 ‘QuartzCore/QuartzCore.h’ 임포트

3. 구현 부분

%d 블로거가 이것을 좋아합니다: