-
Notifications
You must be signed in to change notification settings - Fork 2
/
Switcher1.swift
141 lines (114 loc) · 4.67 KB
/
Switcher1.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
//
// Switcher.swift
// VisionOS Prototypes
//
// Created by Oleg Frolov on 05/01/2024.
//
import SwiftUI
import RealityKit
struct Switcher1: View
{
// Strange bug. You need to have different settings to make it look similar both in the simulator and in the preview
private let dotScale: SIMD3<Float> = [1.0, 1.0, 1.0] // Preview scale
private let dotTranslation: SIMD3<Float> = [0.0, 0.0, -0.175] // Preview offset
// private let dotScale: SIMD3<Float> = [0.75, 0.75, 0.75] // Simulator scale
// private let dotTranslation: SIMD3<Float> = [0.0, 0.0, -0.4525] // Simulator offset
private let dotYOffset: Double = 80.0
private let angleOffset: Double = 10.0
private let animDuration: Double = 1.0
private let flatDotYOffset: Double = 40.0
@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("Left")
Spacer()
.frame(height: 42)
Text("Right")
Spacer()
}
.font(.custom("SF Pro Display", size: 32))
.padding(.leading, 24.0)
Spacer()
}
}
.frame(width: 480, height: 224)
.glassBackgroundEffect()
.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 {
Switcher1()
}