-
Notifications
You must be signed in to change notification settings - Fork 2
/
Switcher2.swift
145 lines (119 loc) · 4.85 KB
/
Switcher2.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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
//
// Switcher.swift
// VisionOS Prototypes
//
// Created by Oleg Frolov on 05/01/2024.
//
import SwiftUI
import RealityKit
struct Switcher2: View
{
// private let dotScale: SIMD3<Float> = [1.0, 1.0, 1.0]
private let dotScale: SIMD3<Float> = [0.75, 0.75, 0.75]
private let dotTranslation: SIMD3<Float> = [0.0, 0.0, -0.4525]
// private let dotTranslation: SIMD3<Float> = [0.0, 0.0, -0.175]
private let dotYOffset: Double = 72.0
private let angleOffset: Double = 10.0
private let animDuration: Double = 1.0
private let flatDotYOffset: Double = 40.0
private let highOpacity: Double = 0.8
private let lowOpacity: Double = 0.2
@State private var isPressed: Bool = false;
@State private var isFirstSelected: Bool = true;
@State private var currentYDotOffset: Double = 0.0
@State private var currentFlatDotYOffset: Double = 0.0
@State private var currentAndleOffset: Double = 0.0
var body: some View
{
VStack
{
HStack(spacing: 0)
{
ZStack
{
Capsule()
.frame(width: 48, height: 128)
.opacity(0.1)
Circle()
.foregroundColor(.black)
.frame(width: 48, height: 48)
.offset(y: -currentFlatDotYOffset)
.animation(.bouncy(duration: animDuration), value: currentFlatDotYOffset)
.opacity(0.5)
.blur(radius: 16)
.blendMode(.multiply)
// Circle()
// .frame(width: 48, height: 48)
// .offset(y: currentFlatDotYOffset)
// .animation(.bouncy(duration: animDuration), value: currentFlatDotYOffset)
// .opacity(0.2)
RealityView
{
content in
async let dot = ModelEntity(named: "sphere_1m")
if let dot = try? await dot
{
dot.transform.scale = dotScale
dot.transform.translation = dotTranslation
content.add(dot)
}
}
.padding3D(.bottom, currentYDotOffset)
.animation(.bouncy(duration: animDuration), value: currentYDotOffset)
}
.frame(width: 48)
.padding(.leading, 48.0)
VStack(alignment: .leading, spacing: 0)
{
Spacer()
Text("Fork").opacity(!isFirstSelected ? lowOpacity : highOpacity)
Spacer()
.frame(height: 42)
Text("Spoon").opacity(isFirstSelected ? lowOpacity : highOpacity)
Spacer()
}
.font(.system(size: 32))
.fontWeight(.regular)
.textCase(/*@START_MENU_TOKEN@*/.uppercase/*@END_MENU_TOKEN@*/)
.kerning(4.0)
.padding(.leading, 24.0)
Spacer()
}
}
.frame(width: 320, height: 224)
.glassBackgroundEffect()
.background(isPressed ? .white.opacity(0.5) : .clear)
.cornerRadius(48)
.gesture(DragGesture(minimumDistance: 0)
.onChanged { _ in
if (!isPressed)
{
isPressed = true
isFirstSelected.toggle()
currentYDotOffset = isFirstSelected ? dotYOffset : -dotYOffset
currentFlatDotYOffset = isFirstSelected ? flatDotYOffset : -flatDotYOffset
currentAndleOffset = isFirstSelected ? angleOffset : -angleOffset
print("Down")
}
}
.onEnded { _ in
if (isPressed)
{
currentAndleOffset = 0.0
isPressed = false
print("Up")
}
})
.onAppear()
{
currentYDotOffset = dotYOffset
currentFlatDotYOffset = flatDotYOffset
}
.offset(z: 24)
.rotation3DEffect(.degrees(currentAndleOffset), axis: (1.0, 0.0, 0.0), anchor: UnitPoint3D(x: 0.0, y: 0.5, z: 0.0))
.animation(.bouncy(duration: animDuration), value: currentAndleOffset)
}
}
#Preview {
Switcher2()
}