-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathSpringyDuoGetStarted.swift
114 lines (95 loc) · 4.37 KB
/
SpringyDuoGetStarted.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
112
113
114
//
// SpringyDuoGetStarted.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.
// Making the resting state bouncy makes the animation more fun and playful
import SwiftUI
struct SpringyDuoGetStarted: 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(.interpolatingSpring(stiffness: 170, damping: 5), 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))
.animation(.interpolatingSpring(stiffness: 800, damping: 5).delay(2), value: isTilting)
// Left and right hands
HStack(spacing: 32) {
Image("legRight")
.rotationEffect(.degrees(isRaising ? 0 : -30), anchor: .bottomLeading)
.offset(x: isRaising ? 5 : 0)
.animation(.interpolatingSpring(stiffness: 170, damping: 8).delay(2), value: isRaising)
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 SpringyDuoGetStarted_Previews: PreviewProvider {
static var previews: some View {
SpringyDuoGetStarted()
.preferredColorScheme(.dark)
}
}