-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathDuoGetStarted.swift
111 lines (94 loc) · 4.01 KB
/
DuoGetStarted.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
//
// DuoGetStarted.swift
// PurposefulSwiftUIAnimations
//
// ANIMATION AND MEANING: Delight and Whimsy
// Yes, you can animate things just for fun and whimsy. The Duolingo getstarted animation makes it fun and delightful to get started to use the app. The playful animation here can help Duolingo win users over other language learning apps.
//
import SwiftUI
struct DuoGetStarted: View {
@State private var isBlinking = false
@State private var isTilting = false
@State private var isRaising = false
@State private var isWaving = false
@State private var isShouting = false
var body: some View {
VStack(spacing: 0) {
VStack {
ZStack {
// Body
Image("body")
HStack(spacing: 82) {
Image("rightHand")
.rotationEffect(.degrees(isWaving ? 0 : 90), anchor: .topTrailing)
Image("leftHand")
.rotationEffect(.degrees(isWaving ? 0 : -10), anchor: .topLeading)
.animation(.easeInOut, value: isWaving)
}
// Face
VStack {
Image("face")
Image("mouth")
}
// Eyes, Nose and thoung
VStack(spacing: -12) {
// Eyes
HStack(spacing: 32) {
ZStack { // Left eye
Image("eyelid")
Image("pipul")
}
ZStack { // Right eye
Image("eyelid")
Image("pipul")
}
}
.scaleEffect(y: isBlinking ? 1 : 0)
// Nose, thoung
VStack(spacing: -8) {
Image("nose")
.zIndex(1)
Image("thoung")
.scaleEffect(x: isShouting ? 1.4 : 1)
.offset(y: isShouting ? -3: 4 )
}
.padding(.bottom)
}
}
.rotationEffect(.degrees(isTilting ? 0 : 15))
// Left and right hands
HStack(spacing: 32) {
Image("legRight")
.rotationEffect(.degrees(isRaising ? 0 : -30), anchor: .bottomLeading)
.offset(x: isRaising ? 5 : 0)
Image("legLeft")
}
} // All views
.onAppear{
withAnimation(.easeOut(duration: 0.2).delay(0.25).repeatCount(2)) {
isBlinking.toggle()
}
withAnimation(.easeInOut(duration: 0.2).delay(0.5*4).repeatCount(1, autoreverses: true)) {
isTilting.toggle()
}
withAnimation(.easeOut(duration: 0.2).repeatCount(11, autoreverses: true)) {
isWaving.toggle()
}
withAnimation(.easeInOut(duration: 1).delay(0.5*3.4).repeatCount(1, autoreverses: true)) {
isRaising.toggle()
}
withAnimation(.easeInOut(duration: 1).delay(0.5*3.4).repeatCount(1, autoreverses: true)) {
isShouting.toggle()
}
}
// Floor
Image("floor")
} // All views
}
}
struct DuoGetStarted_Previews: PreviewProvider {
static var previews: some View {
DuoGetStarted()
.preferredColorScheme(.dark)
}
}