@webspatial/platform-visionos 1.0.5 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -21,13 +21,16 @@ enum SpatialWebMsgType: String, Encodable {
|
|
|
21
21
|
case modelloaded = "modelloaded"
|
|
22
22
|
case modelloadfailed = "modelloadfailed"
|
|
23
23
|
case spatialtap = "spatialtap"
|
|
24
|
+
case spatialdragstart = "spatialdragstart"
|
|
24
25
|
case spatialdrag = "spatialdrag"
|
|
25
26
|
case spatialdragend = "spatialdragend"
|
|
27
|
+
case spatialrotatestart = "spatialrotatestart"
|
|
26
28
|
case spatialrotate = "spatialrotate"
|
|
27
29
|
case spatialrotateend = "spatialrotateend"
|
|
30
|
+
case spatialmagnifystart = "spatialmagnifystart"
|
|
28
31
|
case spatialmagnify = "spatialmagnify"
|
|
29
32
|
case spatialmagnifyend = "spatialmagnifyend"
|
|
30
|
-
|
|
33
|
+
|
|
31
34
|
case objectdestroy = "objectdestroy"
|
|
32
35
|
}
|
|
33
36
|
|
|
@@ -68,6 +71,11 @@ struct WebSpatialDragGuestureEvent: Encodable {
|
|
|
68
71
|
let detail: WebSpatialDragGuestureEventDetail
|
|
69
72
|
}
|
|
70
73
|
|
|
74
|
+
struct WebSpatialDragStartGuestureEvent: Encodable {
|
|
75
|
+
let type: SpatialWebMsgType = SpatialWebMsgType.spatialdragstart
|
|
76
|
+
let detail: WebSpatialDragGuestureEventDetail
|
|
77
|
+
}
|
|
78
|
+
|
|
71
79
|
struct WebSpatialDragEndGuestureEvent: Encodable {
|
|
72
80
|
let type: SpatialWebMsgType = SpatialWebMsgType.spatialdragend
|
|
73
81
|
let detail: WebSpatialDragGuestureEventDetail
|
|
@@ -77,13 +85,18 @@ struct WebSpatialRotateGuestureEventDetail: Encodable {
|
|
|
77
85
|
let rotation: Rotation3D
|
|
78
86
|
let startAnchor3D: UnitPoint3D
|
|
79
87
|
let startLocation3D: Point3D
|
|
80
|
-
|
|
81
88
|
}
|
|
89
|
+
|
|
82
90
|
struct WebSpatialRotateGuestureEvent: Encodable {
|
|
83
91
|
let type: SpatialWebMsgType = SpatialWebMsgType.spatialrotate
|
|
84
92
|
let detail: WebSpatialRotateGuestureEventDetail
|
|
85
93
|
}
|
|
86
94
|
|
|
95
|
+
struct WebSpatialRotateStartGuestureEvent: Encodable {
|
|
96
|
+
let type: SpatialWebMsgType = SpatialWebMsgType.spatialrotatestart
|
|
97
|
+
let detail: WebSpatialRotateGuestureEventDetail
|
|
98
|
+
}
|
|
99
|
+
|
|
87
100
|
struct WebSpatialRotateEndGuestureEvent: Encodable {
|
|
88
101
|
let type: SpatialWebMsgType = SpatialWebMsgType.spatialrotateend
|
|
89
102
|
let detail: WebSpatialRotateGuestureEventDetail
|
|
@@ -101,6 +114,11 @@ struct WebSpatialMagnifyGuestureEvent: Encodable {
|
|
|
101
114
|
let detail: WebSpatialMagnifyGuestureEventDetail
|
|
102
115
|
}
|
|
103
116
|
|
|
117
|
+
struct WebSpatialMagnifyStartGuestureEvent: Encodable {
|
|
118
|
+
let type: SpatialWebMsgType = SpatialWebMsgType.spatialmagnifystart
|
|
119
|
+
let detail: WebSpatialMagnifyGuestureEventDetail
|
|
120
|
+
}
|
|
121
|
+
|
|
104
122
|
struct WebSpatialMagnifyEndGuestureEvent: Encodable {
|
|
105
123
|
let type: SpatialWebMsgType = SpatialWebMsgType.spatialmagnifyend
|
|
106
124
|
let detail: WebSpatialMagnifyGuestureEventDetail
|
|
@@ -5,7 +5,7 @@ var pwaManager = PWAManager()
|
|
|
5
5
|
|
|
6
6
|
struct PWAManager: Codable {
|
|
7
7
|
var isLocal: Bool = false
|
|
8
|
-
var start_url: String = "http://localhost:5173/src/
|
|
8
|
+
var start_url: String = "http://localhost:5173/src/static-3d-model"
|
|
9
9
|
|
|
10
10
|
var scope: String = ""
|
|
11
11
|
var id: String = "com.webspatial.pico"
|
|
@@ -116,6 +116,35 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
116
116
|
return true
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
private func handleNavigationCheckCustom(_ url: URL) -> Bool {
|
|
120
|
+
/*
|
|
121
|
+
because full url is webspatial://createSpatialScene?url=xxx
|
|
122
|
+
we need to get the real url.
|
|
123
|
+
we do 2 things:
|
|
124
|
+
|
|
125
|
+
1. let curUrl = parse url
|
|
126
|
+
2. if url is in scope do webviewModel.load(curUrl)
|
|
127
|
+
else open in safari
|
|
128
|
+
*/
|
|
129
|
+
guard let components = URLComponents(string: url.absoluteString),
|
|
130
|
+
let queryItems = components.queryItems
|
|
131
|
+
else {
|
|
132
|
+
print("❌ fail to parse URL")
|
|
133
|
+
return false
|
|
134
|
+
}
|
|
135
|
+
guard let encodedUrl = queryItems.first(where: { $0.name == "url" })?.value,
|
|
136
|
+
let decodedUrl = encodedUrl.removingPercentEncoding
|
|
137
|
+
else {
|
|
138
|
+
return false
|
|
139
|
+
}
|
|
140
|
+
if pwaManager.checkInScope(url: decodedUrl) {
|
|
141
|
+
spatialWebViewModel.load(decodedUrl)
|
|
142
|
+
return false
|
|
143
|
+
}
|
|
144
|
+
UIApplication.shared.open(URL(string: decodedUrl)!, options: [:], completionHandler: nil)
|
|
145
|
+
return false
|
|
146
|
+
}
|
|
147
|
+
|
|
119
148
|
private func handleWindowOpenCustom(_ url: URL) -> WebViewElementInfo? {
|
|
120
149
|
// get config from url
|
|
121
150
|
guard let components = URLComponents(string: url.absoluteString),
|
|
@@ -132,6 +161,11 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
132
161
|
return nil
|
|
133
162
|
}
|
|
134
163
|
|
|
164
|
+
if !pwaManager.checkInScope(url: decodedUrl) {
|
|
165
|
+
UIApplication.shared.open(URL(string: decodedUrl)!, options: [:], completionHandler: nil)
|
|
166
|
+
return nil
|
|
167
|
+
}
|
|
168
|
+
|
|
135
169
|
if let encodedConfig = queryItems.first(where: { $0.name == "config" })?.value,
|
|
136
170
|
let decodedConfig = encodedConfig.removingPercentEncoding
|
|
137
171
|
{
|
|
@@ -269,6 +303,8 @@ class SpatialScene: SpatialObject, ScrollAbleSpatialElementContainer, WebMsgSend
|
|
|
269
303
|
|
|
270
304
|
spatialWebViewModel
|
|
271
305
|
.addNavigationListener(protocal: SpatialApp.Instance.scope, event: handleNavigationCheck)
|
|
306
|
+
spatialWebViewModel
|
|
307
|
+
.addNavigationListener(protocal: "webspatial://createSpatialScene", event: handleNavigationCheckCustom)
|
|
272
308
|
}
|
|
273
309
|
|
|
274
310
|
var width: Double = 0
|
|
@@ -7,90 +7,159 @@ struct SpatializedDynamic3DView: View {
|
|
|
7
7
|
@State private var isDrag = false
|
|
8
8
|
@State private var isRotate = false
|
|
9
9
|
@State private var isScale = false
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
private var spatializedDynamic3DElement: SpatializedDynamic3DElement {
|
|
12
12
|
return spatializedElement as! SpatializedDynamic3DElement
|
|
13
13
|
}
|
|
14
|
-
|
|
15
|
-
var spatialTapEvent: some Gesture{
|
|
14
|
+
|
|
15
|
+
var spatialTapEvent: some Gesture {
|
|
16
16
|
SpatialTapGesture(count: 1).targetedToAnyEntity()
|
|
17
|
-
.onEnded{ value in
|
|
18
|
-
if let entity = value.entity as? SpatialEntity{
|
|
17
|
+
.onEnded { value in
|
|
18
|
+
if let entity = value.entity as? SpatialEntity {
|
|
19
19
|
spatialScene.sendWebMsg(entity.spatialId, WebSpatialTapGuestureEvent(detail: WebSpatialTapGuestureEventDetail(location3D: value.location3D)))
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
if let spatialEntity = SpatialEntity.findNearestParent(entity: value.entity){
|
|
20
|
+
} else {
|
|
21
|
+
if let spatialEntity = SpatialEntity.findNearestParent(entity: value.entity) {
|
|
23
22
|
spatialScene.sendWebMsg(spatialEntity.spatialId, WebSpatialTapGuestureEvent(detail: WebSpatialTapGuestureEventDetail(location3D: value.location3D)))
|
|
24
23
|
}
|
|
25
24
|
}
|
|
26
|
-
|
|
25
|
+
}
|
|
27
26
|
}
|
|
28
|
-
|
|
29
|
-
var rotate3dEvent: some Gesture{
|
|
30
|
-
RotateGesture3D().targetedToAnyEntity().onChanged{ value in
|
|
31
|
-
|
|
32
|
-
if let entity = value.entity as? SpatialEntity{
|
|
33
|
-
if
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
27
|
+
|
|
28
|
+
var rotate3dEvent: some Gesture {
|
|
29
|
+
RotateGesture3D().targetedToAnyEntity().onChanged { value in
|
|
30
|
+
// Always forward rotate gesture events to JS
|
|
31
|
+
if let entity = value.entity as? SpatialEntity {
|
|
32
|
+
if !isRotate {
|
|
33
|
+
let startEvent = WebSpatialRotateStartGuestureEvent(
|
|
34
|
+
detail: .init(
|
|
35
|
+
rotation: value.rotation,
|
|
36
|
+
startAnchor3D: value.startAnchor3D,
|
|
37
|
+
startLocation3D: value.startLocation3D
|
|
38
|
+
)
|
|
39
|
+
)
|
|
40
|
+
spatialScene.sendWebMsg(entity.spatialId, startEvent)
|
|
41
|
+
isRotate = true
|
|
42
|
+
} else {
|
|
43
|
+
let gestureEvent = WebSpatialRotateGuestureEvent(
|
|
44
|
+
detail: .init(
|
|
45
|
+
rotation: value.rotation,
|
|
46
|
+
startAnchor3D: value.startAnchor3D,
|
|
47
|
+
startLocation3D: value.startLocation3D
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
42
51
|
}
|
|
43
52
|
}
|
|
53
|
+
}.onEnded { value in
|
|
54
|
+
// Always forward rotate end event to JS
|
|
55
|
+
if let entity = value.entity as? SpatialEntity {
|
|
56
|
+
let gestureEvent = WebSpatialRotateEndGuestureEvent(
|
|
57
|
+
detail: .init(
|
|
58
|
+
rotation: value.rotation,
|
|
59
|
+
startAnchor3D: value.startAnchor3D,
|
|
60
|
+
startLocation3D: value.startLocation3D
|
|
61
|
+
)
|
|
62
|
+
)
|
|
63
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
64
|
+
}
|
|
44
65
|
isRotate = false
|
|
45
|
-
}.onEnded{ value in
|
|
46
|
-
print(value.rotation)
|
|
47
|
-
print("rotate end")
|
|
48
|
-
// isRotate = false
|
|
49
66
|
}
|
|
50
67
|
}
|
|
51
|
-
|
|
52
|
-
var magnifyEvent: some Gesture{
|
|
53
|
-
MagnifyGesture().targetedToAnyEntity().onChanged{ value in
|
|
54
|
-
|
|
55
|
-
if let entity = value.entity as? SpatialEntity{
|
|
56
|
-
if
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
68
|
+
|
|
69
|
+
var magnifyEvent: some Gesture {
|
|
70
|
+
MagnifyGesture().targetedToAnyEntity().onChanged { value in
|
|
71
|
+
// Always forward magnify gesture events to JS
|
|
72
|
+
if let entity = value.entity as? SpatialEntity {
|
|
73
|
+
if !isScale {
|
|
74
|
+
let startEvent = WebSpatialMagnifyStartGuestureEvent(
|
|
75
|
+
detail: .init(
|
|
76
|
+
magnification: value.magnification,
|
|
77
|
+
velocity: value.velocity,
|
|
78
|
+
startLocation3D: value.startLocation3D,
|
|
79
|
+
startAnchor3D: value.startAnchor3D
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
spatialScene.sendWebMsg(entity.spatialId, startEvent)
|
|
83
|
+
isScale = true
|
|
84
|
+
} else {
|
|
85
|
+
let gestureEvent = WebSpatialMagnifyGuestureEvent(
|
|
86
|
+
detail: .init(
|
|
87
|
+
magnification: value.magnification,
|
|
88
|
+
velocity: value.velocity,
|
|
89
|
+
startLocation3D: value.startLocation3D,
|
|
90
|
+
startAnchor3D: value.startAnchor3D
|
|
91
|
+
)
|
|
92
|
+
)
|
|
93
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
65
94
|
}
|
|
66
95
|
}
|
|
67
|
-
}.onEnded{ value in
|
|
68
|
-
|
|
69
|
-
|
|
96
|
+
}.onEnded { value in
|
|
97
|
+
// Always forward magnify end event to JS
|
|
98
|
+
if let entity = value.entity as? SpatialEntity {
|
|
99
|
+
let gestureEvent = WebSpatialMagnifyEndGuestureEvent(
|
|
100
|
+
detail: .init(
|
|
101
|
+
magnification: value.magnification,
|
|
102
|
+
velocity: value.velocity,
|
|
103
|
+
startLocation3D: value.startLocation3D,
|
|
104
|
+
startAnchor3D: value.startAnchor3D
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
108
|
+
}
|
|
109
|
+
isScale = false
|
|
70
110
|
}
|
|
71
111
|
}
|
|
72
|
-
|
|
73
|
-
var dragEvent: some Gesture{
|
|
74
|
-
DragGesture().targetedToAnyEntity().onChanged{ value in
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
112
|
+
|
|
113
|
+
var dragEvent: some Gesture {
|
|
114
|
+
DragGesture().targetedToAnyEntity().onChanged { value in
|
|
115
|
+
// Always forward drag gesture events to JS
|
|
116
|
+
if let entity = value.entity as? SpatialEntity {
|
|
117
|
+
if !isDrag {
|
|
118
|
+
let startEvent = WebSpatialDragStartGuestureEvent(
|
|
119
|
+
detail: .init(
|
|
120
|
+
location3D: value.location3D,
|
|
121
|
+
startLocation3D: value.startLocation3D,
|
|
122
|
+
translation3D: value.translation3D,
|
|
123
|
+
predictedEndTranslation3D: value.predictedEndTranslation3D,
|
|
124
|
+
predictedEndLocation3D: value.predictedEndLocation3D,
|
|
125
|
+
velocity: value.velocity
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
spatialScene.sendWebMsg(entity.spatialId, startEvent)
|
|
129
|
+
isDrag = true
|
|
130
|
+
} else {
|
|
131
|
+
let gestureEvent = WebSpatialDragGuestureEvent(
|
|
132
|
+
detail: .init(
|
|
133
|
+
location3D: value.location3D,
|
|
134
|
+
startLocation3D: value.startLocation3D,
|
|
135
|
+
translation3D: value.translation3D,
|
|
136
|
+
predictedEndTranslation3D: value.predictedEndTranslation3D,
|
|
137
|
+
predictedEndLocation3D: value.predictedEndLocation3D,
|
|
138
|
+
velocity: value.velocity
|
|
139
|
+
)
|
|
140
|
+
)
|
|
141
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
85
142
|
}
|
|
86
143
|
}
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
144
|
+
}.onEnded { value in
|
|
145
|
+
// Always forward drag end event to JS
|
|
146
|
+
if let entity = value.entity as? SpatialEntity {
|
|
147
|
+
let gestureEvent = WebSpatialDragEndGuestureEvent(
|
|
148
|
+
detail: .init(
|
|
149
|
+
location3D: value.location3D,
|
|
150
|
+
startLocation3D: value.startLocation3D,
|
|
151
|
+
translation3D: value.translation3D,
|
|
152
|
+
predictedEndTranslation3D: value.predictedEndTranslation3D,
|
|
153
|
+
predictedEndLocation3D: value.predictedEndLocation3D,
|
|
154
|
+
velocity: value.velocity
|
|
155
|
+
)
|
|
156
|
+
)
|
|
157
|
+
spatialScene.sendWebMsg(entity.spatialId, gestureEvent)
|
|
158
|
+
}
|
|
159
|
+
isDrag = false
|
|
91
160
|
}
|
|
92
161
|
}
|
|
93
|
-
|
|
162
|
+
|
|
94
163
|
var body: some View {
|
|
95
164
|
RealityView(make: { content in
|
|
96
165
|
let rootEntity = spatializedDynamic3DElement.getRoot()
|
|
@@ -19,6 +19,7 @@ struct SpatializedStatic3DView: View {
|
|
|
19
19
|
|
|
20
20
|
@ViewBuilder
|
|
21
21
|
var body: some View {
|
|
22
|
+
let depth = spatializedElement.depth
|
|
22
23
|
let transform = spatializedStatic3DElement.modelTransform
|
|
23
24
|
let translation = transform.translation
|
|
24
25
|
let scale = transform.scale
|
|
@@ -41,6 +42,7 @@ struct SpatializedStatic3DView: View {
|
|
|
41
42
|
nil,
|
|
42
43
|
contentMode: .fit
|
|
43
44
|
)
|
|
45
|
+
.if(!depth.isZero){ view in view.scaledToFit3D()}
|
|
44
46
|
.onAppear {
|
|
45
47
|
self.onLoadSuccess()
|
|
46
48
|
}
|