[Animation] interpolatingSpring

알파관·2022년 12월 26일
0
post-thumbnail

0. 공부배경

앱의 SplashView를 구현하는 방식의 일환으로 애니메이션 효과를 적용해보면 어떨까라는 생각이 들어서 여러 리서치 자료를 찾던 중 ìnterpolatingSpring 이라는 것을 알게되었다.

일단 해당 애니메이션은 SwiftUI의 View에 Spring 효과를 입히는 역할을 수행한다.

팀원들과 함께 만들던 앱의 캐릭터(귀여운 곰돌이)가 SplashView에서 Spring 처럼 가볍게 튕겨져 나오면 깜찍하고 괜찮겠다는 생각이들어서 채택을 결심하였다.


1. 공식문서

원하는 메서드를 사용하기 위해서는 공식문서를 꼭 읽어봐야겠죠..?

이번에도 어김없이 바로 검색해서 읽으러가봤습니다

interpolatingSpring(mass:stiffness:damping:initialVelocity:)

An interpolating spring animation that uses a damped spring model to produce values in the range [0, 1] that are then used to interpolate within the [from, to] range of the animated property. Preserves velocity across overlapping animations by adding the effects of each animation.

감쇠 스프링 모델을 사용하여 애니메이션 속성의 [from, to] 범위 내에서 보간하는 데 사용되는 [0, 1] 범위의 값을 생성하는 보간 스프링 애니메이션입니다. 각 애니메이션의 효과를 추가하여 겹치는 애니메이션에서 속도를 유지한다.

겉으로 정의만 읽어봤을 때는 대충 감쇠 스프링효과를 준다~ 정도로 밖에 이해가 되지 않았다.

하지만 이정도 정보만으로도 내가 해당 애니메이션을 사용할 명분은 충분했다.
(희망 애니메이션 구현효과와 정확히 일치하니까)

static func interpolatingSpring(
    mass: Double = 1.0,
    stiffness: Double,
    damping: Double,
    initialVelocity: Double = 0.0
) -> Animation
  • mass

    용수철에 달린 물체의 질량이라고 생각하면 됨.

    무거운 물체가 달려있을수록 스프링이 진동하는 시간이 길어지고 느려지듯이
    mass 값이 커지면 그만큼 진동시간이 증가하게된다.


  • stiffness

    애니메이션의 빠르기를 의미함


  • damping

    스프링 애니메이션의 탄성마찰력에 해당한다

    damping 값이 높아질수록 스프링 애니메이션의 탄성은 떨어진다.


  • initialVelocity

    애니메이션이 변경되는 속도를 의미한다

    공식문서 정의에 명시된 [0, 1] 사이의 값에 해당한다.



매개변수까지 읽어보니까 대충 어떻게 조작할지 감이 잡힐 수 있었다.

내가 원하는 SplashView를 구성하기 위해서는 아래와 같은 조건이 필요했는데, 문서를 읽은 후에 이를 위해서 어떤 값을 조작해야할 지 감을 잡게 되었다.


  1. SplashView는 너무 오래 시간을 잡아먹으면 안됨
    => stiffness를 크게 잡는다
  1. View 객체가 스프링 효과로 진동하는 시간이 너무 길면 안됨
    => mass를 작게하고, damping을 높게 설정한다

세부적인 디테일은 위와 같은 플랜을 가지고 코드구현에 들어간 후에 값을 여러번 변경해가며 정하기로 마음먹었다.


2. 코드구현

@State private var mass: Double = 2
@State private var stiffness: Double = 100
@State private var damping: Double = 13
@State private var initialVelocity: Double = 2
@State private var moveBear = false
@State private var logoOpacity: Double = 0.0

VStack{
  ZStack {
      Image("SplashText")
          .offset(y: -180)
          .opacity(logoOpacity)
  }
  
  ZStack {
      Image("santabear")
        .resizable()
        .frame(width:300, height: 200)
        .offset(y: moveBear ? 500 : 100)                   
        .animation(Animation.interpolatingSpring(mass: mass, 
        stiffness: stiffness, damping: damping, initialVelocity: 
        initialVelocity))
        .onAppear(){
            moveBear.toggle()
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                withAnimation(.easeIn(duration: 1.2)) {
                    initialVelocity = 4
                }
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 1.4) {
                withAnimation(.easeIn(duration: 1.0)) {
                    moveBear.toggle()
                }
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 2.4) {
                withAnimation(.easeIn(duration: 0.6)) {
                    logoOpacity = 0.5
                }
            }
            DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                withAnimation(.easeIn(duration: 1.0)) {
                    logoOpacity = 1
                }
            }
    }
}

코드의 동작과정은 아래와 같다.

  1. SplashView가 켜지면 santabear 이미지를 보여줄지 말지를 알려주는 movebear 상태변수 값이 true로 토글되면서 화면상 y축 500의 위치에 나타난다.

  2. 시작으로부터 0.2초 후에는 애니메이션이 변경되는 속도인 initialVelocity 값을 4로 늘린채 1.2초 동안 애니메이션을 진행한다.

  3. 시작으로부터 1.4초 후엔 movebear 값이 false로 토글되면서 offset 삼항연산식에 적힌 위치로(y축 100) santabear 이미지가 이동하게 된다.

  4. 시작으로부터 2.4초 후엔 앱 로고의 투명도 값인 logoOpacity가 0에서 0.5까지 증가하는 애니메이션이 0.6초 동안 진행된다.
    (안보이던 앱 로고가 희미하게 보이게 됨)

  5. 시작으로부터 3초 후엔 앱 로고의 투명도 값인 logoOpacity가 0.5에서 1까지 증가하는 애니메이션이 1.0초 동안 진행된다.
    (희미하게 보이던 앱 로고가 또렷하게 보이게 됨)


3. 결과화면

위 코드를 바탕으로 코드를 실행하면 아래와 같은 애니메이션 SplashView를 볼 수 있게 된다.

곰돌이 위의 나무는 그냥 이미지를 덧붙인 것이고, 눈 내리는 효과는 또다른 레퍼런스를 참고하여 제작하였다.

눈 효과 애니메이션은 추후에 따로 포스팅을 진행하겠다!

(곰돌이 가와~~이)


참고링크

https://medium.com/@amosgyamfi/learning-swiftui-spring-animations-the-basics-and-beyond-4fb032212487

https://developer.apple.com/documentation/swiftui/animation/interpolatingspring(mass:stiffness:damping:initialvelocity:)

profile
iOS🍎

0개의 댓글