공식문서에 정의된 dashPhase의 의미는 “How far into the dash pattern the line starts.”입니다. 점선 패턴 (dash pattern)의 시작 위치를 어디로 할 것인가입니다.
아래 예시를 보여드리겠습니다. 아래 두 사각형은 dash: [10, 10]의 점선으로 이루어져있는데요. 위 사각형은 dashPhase가 0이고 아래 사각형은 dashPhase가 10입니다.
위 사각형은 사각형의 좌상단에서 부터 dash가 바로 시작하는 한편 아래 사각형은 위 사각형의 dash보다 시계방향으로 10pt 씩 밀려있는 것을 볼 수 있습니다.
VStack {
Color
.blue
.frame(width: 100, height: 100)
.mask(Rectangle()
.stroke(style: StrokeStyle(lineWidth: 5,
lineCap: .round,
dash: [10, 10],
dashPhase: 0))
)
Color
.blue
.frame(width: 100, height: 100)
.mask(Rectangle()
.stroke(style: StrokeStyle(lineWidth: 5,
lineCap: .round,
dash: [10, 10],
dashPhase: 10))
)
}
이 속성 역시도 애니메이션을 적용할 수 있는 속성입니다. 이 속성을 활용해서 dash pattern을 이동시켜 아래와 같은 애니메이션을 만들어 봅시다.
이 애니메이션을 만들 때 주의할 점은 dashPhase의 시작점과 끝점을 어떻게 할 것인가입니다. 이 애니메이션은 무한 반복을 전제로 하기 때문에 dashPhase의 시작점과 끝점은 View의 모양이 같지 않으면 한 번의 애니메이션이 끝나고 반복해서 다시 시작되는 부분에 버벅일 수 있습니다.
따라서 가장 최적화된 패턴은 dash와 dash 사이의 간격이 모두 이동한 이후에 다른 애니메이션을 시작하는 것입니다. 따라서 dash: [10, 10]이라면 10 + 10 = 20으로 dashPhase의 시작점과 끝점의 차이를 정하는 것입니다.
그리고 추가적으로 회전하는 방향이 있는데요. 지금처럼 시계방향 회전을 시키려면 dashPhase의 끝점을 음수로 시계반대방향이라면 dashPhase를 양수로 설정하면 됩니다.
struct Animation: View {
// 1. trigger 변수
@State private var dashPhase: CGFloat = 0
var body: some View {
Color
.blue
.frame(width: 100, height: 100)
.mask(Rectangle()
// 2. 애니메이션이 가능한 속성에 trigger 변수 연결
.stroke(style: StrokeStyle(lineWidth: 5, lineCap: .round, dash: [10, 10], dashPhase: dashPhase))
// 3. 애니메이션 정의
.animation(.linear.repeatForever(autoreverses: false).speed(0.1), value: dashPhase)
)
.onAppear {
// 4. 애니메이션의 시작점에서 trigger 변수 변경
dashPhase = -20
}
}
}