@webspatial/builder 0.0.9 → 0.0.11
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/dist/index.js +1 -1
- package/dist/lib/Cli.js +1 -1
- package/dist/lib/cmds/build.d.ts +1 -1
- package/dist/lib/cmds/build.js +1 -1
- package/dist/lib/cmds/check.js +1 -1
- package/dist/lib/cmds/help.js +1 -1
- package/dist/lib/cmds/version.js +1 -1
- package/dist/lib/pwa/config.js +1 -1
- package/dist/lib/pwa/index.js +1 -1
- package/dist/lib/pwa/validate.js +1 -1
- package/dist/lib/resource/file.js +1 -1
- package/dist/lib/resource/imageHelper.js +1 -1
- package/dist/lib/resource/index.d.ts +10 -3
- package/dist/lib/resource/index.js +1 -1
- package/dist/lib/resource/load.js +1 -1
- package/dist/lib/utils/CustomError.js +1 -1
- package/dist/lib/utils/FetchUtils-1.js +1 -1
- package/dist/lib/utils/Log.js +1 -1
- package/dist/lib/utils/fetch.js +1 -1
- package/dist/lib/utils/messages.js +1 -1
- package/dist/lib/utils/utils.d.ts +9 -0
- package/dist/lib/utils/utils.js +1 -1
- package/dist/lib/xcode/index.js +1 -1
- package/dist/lib/xcode/manifestSwiftTemplate.d.ts +1 -1
- package/dist/lib/xcode/manifestSwiftTemplate.js +1 -1
- package/dist/lib/xcode/xcodebuild.js +1 -1
- package/dist/lib/xcode/xcodeproject.js +1 -1
- package/dist/lib/xcode/xcrun.js +1 -1
- package/package.json +3 -2
- package/template/visionOSApp/Packages/RealityKitContent/.build/workspace-state.json +0 -7
- package/template/visionOSApp/Packages/RealityKitContent/.swiftpm/xcode/xcuserdata/bytedance.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
- package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json +0 -11
- package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json +0 -112
- package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata +0 -17
- package/template/visionOSApp/Packages/RealityKitContent/Package.swift +0 -27
- package/template/visionOSApp/Packages/RealityKitContent/README.md +0 -3
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Immersive.usda +0 -50
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda +0 -216
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda +0 -59
- package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift +0 -4
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json +0 -12
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Contents.json +0 -17
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json +0 -12
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json +0 -12
- package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Assets.xcassets/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/Info.plist +0 -33
- package/template/visionOSApp/web-spatial/Preview Content/Preview Assets.xcassets/Contents.json +0 -6
- package/template/visionOSApp/web-spatial/libs/EventEmitter.swift +0 -32
- package/template/visionOSApp/web-spatial/libs/SpatialComponent.swift +0 -31
- package/template/visionOSApp/web-spatial/libs/SpatialEntity.swift +0 -179
- package/template/visionOSApp/web-spatial/libs/SpatialInputComponent.swift +0 -26
- package/template/visionOSApp/web-spatial/libs/SpatialMeshResource.swift +0 -19
- package/template/visionOSApp/web-spatial/libs/SpatialModel3DComponent.swift +0 -51
- package/template/visionOSApp/web-spatial/libs/SpatialModelComponent.swift +0 -32
- package/template/visionOSApp/web-spatial/libs/SpatialObject.swift +0 -144
- package/template/visionOSApp/web-spatial/libs/SpatialPhysicallyBasedMaterial.swift +0 -19
- package/template/visionOSApp/web-spatial/libs/SpatialViewComponent.swift +0 -15
- package/template/visionOSApp/web-spatial/libs/SpatialWindowComponent.swift +0 -420
- package/template/visionOSApp/web-spatial/libs/SpatialWindowContainer.swift +0 -149
- package/template/visionOSApp/web-spatial/libs/Utils/CommandManager.swift +0 -800
- package/template/visionOSApp/web-spatial/libs/Utils/Logger.swift +0 -36
- package/template/visionOSApp/web-spatial/libs/Utils/SceneManager.swift +0 -108
- package/template/visionOSApp/web-spatial/libs/Utils/WindowContainerMgr.swift +0 -113
- package/template/visionOSApp/web-spatial/libs/json/JsonParser.swift +0 -52
- package/template/visionOSApp/web-spatial/libs/uiKitDelegate/Window.swift +0 -34
- package/template/visionOSApp/web-spatial/libs/webView/UpdateSystem.swift +0 -33
- package/template/visionOSApp/web-spatial/libs/webView/backend/NativeWebView.swift +0 -319
- package/template/visionOSApp/web-spatial/libs/webView/manifest.swift +0 -92
- package/template/visionOSApp/web-spatial/static-web/index.html +0 -9
- package/template/visionOSApp/web-spatial/views/HideViewModifier.swift +0 -17
- package/template/visionOSApp/web-spatial/views/ImmersiveView.swift +0 -24
- package/template/visionOSApp/web-spatial/views/LoadingView.swift +0 -25
- package/template/visionOSApp/web-spatial/views/MaterialWithBorderCornerModifier.swift +0 -82
- package/template/visionOSApp/web-spatial/views/OpenDismissHandlerUI.swift +0 -52
- package/template/visionOSApp/web-spatial/views/PlainWindowContainerView.swift +0 -84
- package/template/visionOSApp/web-spatial/views/SpatialModel3DView.swift +0 -193
- package/template/visionOSApp/web-spatial/views/SpatialViewUI.swift +0 -168
- package/template/visionOSApp/web-spatial/views/SpatialWebViewUI.swift +0 -186
- package/template/visionOSApp/web-spatial/views/VolumetricWindowContainerView.swift +0 -38
- package/template/visionOSApp/web-spatial/views/ui/NavView.swift +0 -125
- package/template/visionOSApp/web-spatial/web_spatialApp.swift +0 -158
- package/template/visionOSApp/web-spatial.xcodeproj/project.pbxproj +0 -686
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +0 -5
- package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcuserdata/bytedance.xcuserdatad/WorkspaceSettings.xcsettings +0 -14
- package/template/visionOSApp/web-spatial.xcodeproj/xcshareddata/xcschemes/web-spatial.xcscheme +0 -115
- package/template/visionOSApp/web-spatial.xcodeproj/xcuserdata/bytedance.xcuserdatad/xcschemes/xcschememanagement.plist +0 -27
- package/template/visionOSApp/web-spatialTests/web_spatialTests.swift +0 -34
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
import Foundation
|
|
3
|
-
|
|
4
|
-
var pwaManager = PWAManager()
|
|
5
|
-
|
|
6
|
-
struct PWAManager: Codable {
|
|
7
|
-
var isLocal: Bool = false
|
|
8
|
-
var start_url: String = "http://localhost:5173/"
|
|
9
|
-
var scope: String = ""
|
|
10
|
-
var id: String = "com.webspatial.pico"
|
|
11
|
-
|
|
12
|
-
var name: String = "WebSpatial"
|
|
13
|
-
var short_name: String = "name"
|
|
14
|
-
var description: String = ""
|
|
15
|
-
|
|
16
|
-
var display: PWADisplayMode = .minimal
|
|
17
|
-
var display_override: [PWADisplayMode] = []
|
|
18
|
-
var protocol_handlers: [PWAProtocol] = [PWAProtocol(protocolValue: "web+spatial", url: "./?cmd=%s")]
|
|
19
|
-
var mainScene: WindowContainerOptions = .init(
|
|
20
|
-
defaultSize: .init(
|
|
21
|
-
width: 1280,
|
|
22
|
-
height: 720
|
|
23
|
-
),
|
|
24
|
-
resizability: "automatic"
|
|
25
|
-
)
|
|
26
|
-
var useMainScene: Bool = true
|
|
27
|
-
|
|
28
|
-
mutating func _init() {
|
|
29
|
-
let urlType = start_url.split(separator: "://").first
|
|
30
|
-
if !(urlType == "http" || urlType == "https") {
|
|
31
|
-
start_url = Bundle.main.url(forResource: start_url, withExtension: "", subdirectory: "")!.absoluteString
|
|
32
|
-
scope = "file://" + Bundle.main.bundlePath + "/" + scope
|
|
33
|
-
scope = scope.replacingOccurrences(of: " ", with: "%20")
|
|
34
|
-
isLocal = true
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if display_override.count > 0 {
|
|
38
|
-
display = display_override[0]
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
for i in 0 ... protocol_handlers.count - 1 {
|
|
42
|
-
let item = protocol_handlers[i]
|
|
43
|
-
protocol_handlers[i].updateUrl(scope + item.url)
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
func checkInScope(url: String) -> Bool {
|
|
48
|
-
return url.starts(with: scope)
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// web+spatial://test
|
|
52
|
-
func checkInDeeplink(url: String) -> String {
|
|
53
|
-
var linkUrl: String = url
|
|
54
|
-
for item in protocol_handlers {
|
|
55
|
-
if linkUrl.starts(with: item.protocolValue) {
|
|
56
|
-
let queryString: String = linkUrl.replacingOccurrences(of: item.protocolValue, with: "").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
|
|
57
|
-
linkUrl = item.url.replacingOccurrences(of: "%s", with: item.protocolValue + queryString)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
logger.debug(linkUrl)
|
|
61
|
-
return linkUrl
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
func getLocalResourceURL(url: String) -> String {
|
|
65
|
-
let path = String(url.split(separator: "file://").first!.split(separator: "?").first!)
|
|
66
|
-
let root = String(url.split(separator: "?").first!)
|
|
67
|
-
let params = String(url.split(separator: "file://" + root).first!)
|
|
68
|
-
var resource: String = Bundle.main.url(forResource: path, withExtension: "", subdirectory: "")?.absoluteString ?? ""
|
|
69
|
-
if resource == "" {
|
|
70
|
-
resource = Bundle.main.url(forResource: "static-web" + path, withExtension: "", subdirectory: "")?.absoluteString ?? ""
|
|
71
|
-
}
|
|
72
|
-
if resource == "" {
|
|
73
|
-
return url
|
|
74
|
-
}
|
|
75
|
-
resource += "?" + params
|
|
76
|
-
return resource
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
enum PWADisplayMode: Codable {
|
|
81
|
-
case minimal
|
|
82
|
-
case standalone
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
struct PWAProtocol: Codable {
|
|
86
|
-
var protocolValue: String = ""
|
|
87
|
-
var url: String = ""
|
|
88
|
-
|
|
89
|
-
mutating func updateUrl(_ str: String) {
|
|
90
|
-
url = str
|
|
91
|
-
}
|
|
92
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import SwiftUI
|
|
2
|
-
|
|
3
|
-
struct HideViewModifier: ViewModifier {
|
|
4
|
-
let isHidden: Bool
|
|
5
|
-
@ViewBuilder func body(content: Content) -> some View {
|
|
6
|
-
content
|
|
7
|
-
.opacity(isHidden ? 0 : 1)
|
|
8
|
-
.disabled(isHidden)
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Extending on View to apply to all Views
|
|
13
|
-
extension View {
|
|
14
|
-
func hidden(_ isHidden: Bool) -> some View {
|
|
15
|
-
modifier(HideViewModifier(isHidden: isHidden))
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// ImmersiveView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 5/8/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import RealityKit
|
|
9
|
-
import RealityKitContent
|
|
10
|
-
import SwiftUI
|
|
11
|
-
|
|
12
|
-
struct ImmersiveView: View {
|
|
13
|
-
var body: some View {
|
|
14
|
-
RealityView { content in
|
|
15
|
-
if let scene = try? await Entity(named: "Immersive", in: realityKitContentBundle) {
|
|
16
|
-
content.add(scene)
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
#Preview(immersionStyle: .mixed) {
|
|
23
|
-
ImmersiveView()
|
|
24
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// LoadingView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 2025/1/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import SwiftUI
|
|
9
|
-
import SwiftUICore
|
|
10
|
-
|
|
11
|
-
struct LoadingView: View {
|
|
12
|
-
var body: some View {
|
|
13
|
-
ZStack {
|
|
14
|
-
VStack {
|
|
15
|
-
ProgressView()
|
|
16
|
-
.progressViewStyle(CircularProgressViewStyle(tint: .white))
|
|
17
|
-
.scaleEffect(2)
|
|
18
|
-
Text("Loading...")
|
|
19
|
-
.foregroundColor(.white)
|
|
20
|
-
.font(.headline)
|
|
21
|
-
.padding(.top, 16)
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// MaterialWithBorderCornerModifier.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 12/4/24.
|
|
6
|
-
//
|
|
7
|
-
import SwiftUI
|
|
8
|
-
|
|
9
|
-
enum BackgroundMaterial: String, Codable {
|
|
10
|
-
case None = "none"
|
|
11
|
-
case Transparent = "transparent"
|
|
12
|
-
case GlassMaterial = "translucent"
|
|
13
|
-
case ThickMaterial = "thick"
|
|
14
|
-
case RegularMaterial = "regular"
|
|
15
|
-
case ThinMaterial = "thin"
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
struct CornerRadius: Codable {
|
|
19
|
-
var topLeading: CGFloat = 0
|
|
20
|
-
var bottomLeading: CGFloat = 0
|
|
21
|
-
var topTrailing: CGFloat = 0
|
|
22
|
-
var bottomTrailing: CGFloat = 0
|
|
23
|
-
|
|
24
|
-
func toJson() -> [String: Any] {
|
|
25
|
-
return [
|
|
26
|
-
"topLeading": topLeading,
|
|
27
|
-
"bottomLeading": bottomLeading,
|
|
28
|
-
"topTrailing": topTrailing,
|
|
29
|
-
"bottomTrailing": bottomTrailing,
|
|
30
|
-
]
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
struct MaterialWithBorderCornerModifier: ViewModifier {
|
|
35
|
-
let backgroundMaterial: BackgroundMaterial
|
|
36
|
-
let cornerRadius: CornerRadius
|
|
37
|
-
|
|
38
|
-
init(_ backgroundMaterial: BackgroundMaterial, _ cornerRadius: CornerRadius) {
|
|
39
|
-
self.backgroundMaterial = backgroundMaterial
|
|
40
|
-
self.cornerRadius = cornerRadius
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
func body(content: Content) -> some View {
|
|
44
|
-
let radii = RectangleCornerRadii(topLeading: cornerRadius.topLeading, bottomLeading: cornerRadius.bottomLeading, bottomTrailing: cornerRadius.bottomTrailing, topTrailing: cornerRadius.topTrailing)
|
|
45
|
-
|
|
46
|
-
switch backgroundMaterial {
|
|
47
|
-
case .GlassMaterial:
|
|
48
|
-
content
|
|
49
|
-
.glassBackgroundEffect(
|
|
50
|
-
in: .rect(cornerRadii: radii),
|
|
51
|
-
displayMode: .always
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
case .RegularMaterial:
|
|
55
|
-
content
|
|
56
|
-
.background(Material.regularMaterial)
|
|
57
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
58
|
-
|
|
59
|
-
case .ThinMaterial:
|
|
60
|
-
content
|
|
61
|
-
.background(Material.thinMaterial)
|
|
62
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
63
|
-
|
|
64
|
-
case .ThickMaterial:
|
|
65
|
-
content
|
|
66
|
-
.background(Material.thickMaterial)
|
|
67
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
68
|
-
|
|
69
|
-
default:
|
|
70
|
-
content
|
|
71
|
-
.clipShape(.rect(cornerRadii: radii))
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
extension View {
|
|
77
|
-
func materialWithBorderCorner(_ backgroundMaterial: BackgroundMaterial, _ cornerRadius: CornerRadius) -> some View {
|
|
78
|
-
return modifier(
|
|
79
|
-
MaterialWithBorderCornerModifier(backgroundMaterial, cornerRadius)
|
|
80
|
-
)
|
|
81
|
-
}
|
|
82
|
-
}
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// OpenDismissHandlerUI.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 8/20/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import SwiftUI
|
|
9
|
-
|
|
10
|
-
struct OpenDismissHandlerUI: View {
|
|
11
|
-
@Environment(\.openImmersiveSpace) private var openImmersiveSpace
|
|
12
|
-
@Environment(\.dismissImmersiveSpace) private var dismissImmersiveSpace
|
|
13
|
-
@Environment(\.openWindow) private var openWindow
|
|
14
|
-
@Environment(\.dismissWindow) private var dismissWindow
|
|
15
|
-
|
|
16
|
-
@Environment(SpatialWindowContainer.self) var windowContainerContent: SpatialWindowContainer
|
|
17
|
-
|
|
18
|
-
@Environment(\.scenePhase) private var scenePhase
|
|
19
|
-
|
|
20
|
-
var body: some View {
|
|
21
|
-
VStack {}
|
|
22
|
-
.onAppear()
|
|
23
|
-
.onReceive(windowContainerContent.toggleImmersiveSpace) { v in
|
|
24
|
-
if v {
|
|
25
|
-
Task {
|
|
26
|
-
await openImmersiveSpace(id: "ImmersiveSpace")
|
|
27
|
-
}
|
|
28
|
-
} else {
|
|
29
|
-
Task {
|
|
30
|
-
await dismissImmersiveSpace()
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
.onReceive(windowContainerContent.openWindowData) { wd in
|
|
35
|
-
let _ = openWindow(id: wd.windowStyle, value: wd)
|
|
36
|
-
}
|
|
37
|
-
.onReceive(windowContainerContent.closeWindowData) { wd in
|
|
38
|
-
dismissWindow(id: wd.windowStyle, value: wd)
|
|
39
|
-
}
|
|
40
|
-
.onReceive(windowContainerContent.setLoadingWindowData) { wd in
|
|
41
|
-
if wd.method == .show {
|
|
42
|
-
openWindow(id: "loading")
|
|
43
|
-
} else if wd.method == .hide {
|
|
44
|
-
dismissWindow(id: "loading")
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
.onChange(of: scenePhase) { oldValue, newValue in
|
|
49
|
-
logger.debug("OpenDismissHandlerUI: Value changed from \(oldValue) to \(newValue)")
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// PlainWindowContainerView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 5/9/24.
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
import RealityKit
|
|
9
|
-
import SwiftUI
|
|
10
|
-
|
|
11
|
-
struct PlainWindowContainerView: View {
|
|
12
|
-
@EnvironmentObject private var sceneDelegate: SceneDelegate
|
|
13
|
-
@Environment(SpatialWindowContainer.self) private var windowContainerContent: SpatialWindowContainer
|
|
14
|
-
|
|
15
|
-
@State private var windowResizeInProgress = false
|
|
16
|
-
@State private var timer: Timer?
|
|
17
|
-
|
|
18
|
-
private func setSize(size: CGSize) {
|
|
19
|
-
sceneDelegate.window?.windowScene?.requestGeometryUpdate(.Vision(size: size))
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
var body: some View {
|
|
23
|
-
OpenDismissHandlerUI().environment(windowContainerContent).onDisappear {
|
|
24
|
-
windowContainerContent.destroy()
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
let rootEntity = windowContainerContent.getEntities().filter {
|
|
28
|
-
$0.value.getComponent(SpatialWindowComponent.self) != nil && $0.value.coordinateSpace == .ROOT
|
|
29
|
-
}.first?.value
|
|
30
|
-
|
|
31
|
-
GeometryReader { proxy3D in
|
|
32
|
-
ZStack {
|
|
33
|
-
if let e = rootEntity {
|
|
34
|
-
let _ = e.forceUpdate ? 0 : 0
|
|
35
|
-
let x = proxy3D.size.width / 2
|
|
36
|
-
let y = proxy3D.size.height / 2
|
|
37
|
-
let z = CGFloat(e.modelEntity.position.z)
|
|
38
|
-
let width = proxy3D.size.width
|
|
39
|
-
let height = proxy3D.size.height
|
|
40
|
-
|
|
41
|
-
if windowResizeInProgress {
|
|
42
|
-
VStack {}.frame(width: width, height: height).glassBackgroundEffect().padding3D(.front, -100_000)
|
|
43
|
-
.position(x: x, y: y)
|
|
44
|
-
.offset(z: z)
|
|
45
|
-
} else {
|
|
46
|
-
// Avoid showing webview until its loading completes
|
|
47
|
-
let wc = e.getComponent(SpatialWindowComponent.self)
|
|
48
|
-
let didFinishFirstLoad = wc != nil ? wc!.didFinishFirstLoad : false
|
|
49
|
-
|
|
50
|
-
SpatialWebViewUI().environment(e)
|
|
51
|
-
.frame(width: width, height: height).padding3D(.front, -100_000)
|
|
52
|
-
.rotation3DEffect(Rotation3D(simd_quatf(ix: e.modelEntity.orientation.vector.x, iy: e.modelEntity.orientation.vector.y, iz: e.modelEntity.orientation.vector.z, r: e.modelEntity.orientation.vector.w)))
|
|
53
|
-
.position(x: x, y: y)
|
|
54
|
-
.offset(z: z)
|
|
55
|
-
.opacity(didFinishFirstLoad ? 1.0 : 0.0)
|
|
56
|
-
.animation(.linear(duration: 0.2), value: didFinishFirstLoad)
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
.onReceive(windowContainerContent.setSize) { newSize in
|
|
61
|
-
setSize(size: newSize)
|
|
62
|
-
}
|
|
63
|
-
.onChange(of: proxy3D.size) {
|
|
64
|
-
// WkWebview has an issue where it doesn't resize while the swift window is resized
|
|
65
|
-
// Treid to call didMoveToWindow to force redraw to occur but that seemed to cause rendering artifacts so that solution was rejected
|
|
66
|
-
// Now we use a windowResizeInProgress state to hide the webview (by removoving from the view) and other content (using opacity).
|
|
67
|
-
// After resize is completed the webview is added back to the page which causes a redraw at the correct dimensions/position
|
|
68
|
-
if let wv = rootEntity?.getComponent(SpatialWindowComponent.self) {
|
|
69
|
-
windowResizeInProgress = true
|
|
70
|
-
if timer != nil {
|
|
71
|
-
timer!.invalidate()
|
|
72
|
-
}
|
|
73
|
-
// If we don't detect resolution change after x seconds we treat the resize as complete
|
|
74
|
-
timer = Timer.scheduledTimer(withTimeInterval: 0.2, repeats: false) { _ in
|
|
75
|
-
windowResizeInProgress = false
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Trigger resize in the webview's body width and fire a window resize event to get the JS on the page to update state while dragging occurs
|
|
79
|
-
wv.evaluateJS(js: "var tempWidth_ = document.body.style.width;document.body.style.width='" + String(Float(proxy3D.size.width)) + "px'; window.dispatchEvent(new Event('resize'));")
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
//
|
|
2
|
-
// SpatialModel3DView.swift
|
|
3
|
-
// web-spatial
|
|
4
|
-
//
|
|
5
|
-
// Created by ByteDance on 1/21/25.
|
|
6
|
-
//
|
|
7
|
-
import RealityKit
|
|
8
|
-
import SwiftUI
|
|
9
|
-
|
|
10
|
-
class SpatialModel3DViewGestureData {
|
|
11
|
-
// for dragging state
|
|
12
|
-
var isDragging = false
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
struct SpatialModel3DView: View {
|
|
16
|
-
@Environment(SpatialEntity.self) var e: SpatialEntity
|
|
17
|
-
var parentYOffset = Float(0.0)
|
|
18
|
-
|
|
19
|
-
@State private var gestureData = SpatialModel3DViewGestureData()
|
|
20
|
-
|
|
21
|
-
var drag: some Gesture {
|
|
22
|
-
DragGesture()
|
|
23
|
-
.onChanged(onDragging)
|
|
24
|
-
.onEnded(onDraggingEnded)
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
var tapGesture: some Gesture {
|
|
28
|
-
TapGesture(count: 1)
|
|
29
|
-
.onEnded(onTapEnded)
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
var doubleTapGesture: some Gesture {
|
|
33
|
-
TapGesture(count: 2)
|
|
34
|
-
.onEnded(onDoubleTapEnded)
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
var longPressGesture: some Gesture {
|
|
38
|
-
LongPressGesture(minimumDuration: 1.0)
|
|
39
|
-
.onEnded(onLonePressEnded)
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
@ViewBuilder
|
|
43
|
-
var body: some View {
|
|
44
|
-
if e.coordinateSpace == .DOM {
|
|
45
|
-
if let childModel3DComponent = e.getComponent(SpatialModel3DComponent.self),
|
|
46
|
-
let url = URL(string: childModel3DComponent.modelURL)
|
|
47
|
-
{
|
|
48
|
-
let x = CGFloat(e.modelEntity.position.x)
|
|
49
|
-
let y = CGFloat(e.modelEntity.position.y - (childModel3DComponent.scrollWithParent ? parentYOffset : 0))
|
|
50
|
-
let z = CGFloat(e.modelEntity.position.z)
|
|
51
|
-
let width = CGFloat(childModel3DComponent.resolutionX)
|
|
52
|
-
let height = CGFloat(childModel3DComponent.resolutionY)
|
|
53
|
-
let anchor = childModel3DComponent.rotationAnchor
|
|
54
|
-
let opacity = childModel3DComponent.opacity
|
|
55
|
-
let resizable = childModel3DComponent.resizable
|
|
56
|
-
let aspectRatio: CGFloat? = childModel3DComponent.aspectRatio == nil ? nil : CGFloat(childModel3DComponent.aspectRatio!)
|
|
57
|
-
let contentMode = childModel3DComponent.contentMode
|
|
58
|
-
|
|
59
|
-
let enableTapEvent = childModel3DComponent.enableTapEvent
|
|
60
|
-
let enableDoubleTapEvent = childModel3DComponent.enableDoubleTapEvent
|
|
61
|
-
let enableDragEvent = childModel3DComponent.enableDragEvent
|
|
62
|
-
let enableLongPressEvent = childModel3DComponent.enableLongPressEvent
|
|
63
|
-
|
|
64
|
-
// Matrix = MTranslate X MRotate X MScale
|
|
65
|
-
Model3D(url: url) { newPhase in
|
|
66
|
-
switch newPhase {
|
|
67
|
-
case .empty:
|
|
68
|
-
ProgressView()
|
|
69
|
-
|
|
70
|
-
case let .success(resolvedModel3D):
|
|
71
|
-
resolvedModel3D
|
|
72
|
-
.resizable(resizable)
|
|
73
|
-
.aspectRatio(
|
|
74
|
-
aspectRatio,
|
|
75
|
-
contentMode: contentMode
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
.onAppear {
|
|
79
|
-
self.onLoadSuccess()
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
case let .failure(error):
|
|
83
|
-
// use UIView.onAppear to notify error phase.
|
|
84
|
-
Text("").onAppear {
|
|
85
|
-
self.onLoadFailure(error.localizedDescription)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
@unknown default:
|
|
89
|
-
EmptyView()
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
.frame(width: width, height: height)
|
|
93
|
-
// .background(Color.blue)
|
|
94
|
-
.scaleEffect(
|
|
95
|
-
x: CGFloat(e.modelEntity.scale.x),
|
|
96
|
-
y: CGFloat(e.modelEntity.scale.y),
|
|
97
|
-
z: CGFloat(e.modelEntity.scale.z),
|
|
98
|
-
anchor: anchor
|
|
99
|
-
)
|
|
100
|
-
.rotation3DEffect(
|
|
101
|
-
Rotation3D(simd_quatf(
|
|
102
|
-
ix: e.modelEntity.orientation.vector.x,
|
|
103
|
-
iy: e.modelEntity.orientation.vector.y,
|
|
104
|
-
iz: e.modelEntity.orientation.vector.z,
|
|
105
|
-
r: e.modelEntity.orientation.vector.w
|
|
106
|
-
)),
|
|
107
|
-
anchor: anchor
|
|
108
|
-
)
|
|
109
|
-
.position(x: x, y: y)
|
|
110
|
-
.offset(z: z)
|
|
111
|
-
.frame(maxDepth: 0, alignment: .back)
|
|
112
|
-
.opacity(opacity)
|
|
113
|
-
.gesture(enableDragEvent ? drag : nil)
|
|
114
|
-
.gesture(enableDoubleTapEvent ?doubleTapGesture : nil)
|
|
115
|
-
.gesture(enableTapEvent ? tapGesture : nil)
|
|
116
|
-
.gesture(enableLongPressEvent ? longPressGesture : nil)
|
|
117
|
-
.hidden(!e.visible)
|
|
118
|
-
} else {
|
|
119
|
-
Text("").onAppear {
|
|
120
|
-
self.onLoadFailure("invalid URL")
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
} else {
|
|
124
|
-
EmptyView()
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
private func onLoadSuccess() {
|
|
129
|
-
if let model3DComponent = e.getComponent(SpatialModel3DComponent.self) {
|
|
130
|
-
let data = "{eventType: 'phase', value: 'success'}"
|
|
131
|
-
model3DComponent.wv?.fireComponentEvent(componentId: model3DComponent.id, data: data)
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
private func onLoadFailure(_ error: String) {
|
|
136
|
-
if let model3DComponent = e.getComponent(SpatialModel3DComponent.self) {
|
|
137
|
-
let data = "{eventType: 'phase', value: 'failure', error: '\(error)'} "
|
|
138
|
-
model3DComponent.wv?.fireComponentEvent(componentId: model3DComponent.id, data: data)
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private func onDragging(dragValue: DragGesture.Value) {
|
|
143
|
-
var eventType = "drag"
|
|
144
|
-
if !gestureData.isDragging {
|
|
145
|
-
gestureData.isDragging = true
|
|
146
|
-
eventType = "dragstart"
|
|
147
|
-
}
|
|
148
|
-
fireDragEvent(eventType, dragValue)
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
private func onDraggingEnded(dragValue: DragGesture.Value) {
|
|
152
|
-
gestureData.isDragging = false
|
|
153
|
-
let eventType = "dragend"
|
|
154
|
-
fireDragEvent(eventType, dragValue)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
private func onTapEnded(_: TapGesture.Value) {
|
|
158
|
-
print("onTapEnded")
|
|
159
|
-
if let model3DComponent = e.getComponent(SpatialModel3DComponent.self) {
|
|
160
|
-
let eventType = "tap"
|
|
161
|
-
let data = "{eventType: '\(eventType)' } "
|
|
162
|
-
model3DComponent.wv?.fireComponentEvent(componentId: model3DComponent.id, data: data)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
private func onDoubleTapEnded(_: TapGesture.Value) {
|
|
167
|
-
print("onDoubleTapEnded")
|
|
168
|
-
if let model3DComponent = e.getComponent(SpatialModel3DComponent.self) {
|
|
169
|
-
let eventType = "doubletap"
|
|
170
|
-
let data = "{eventType: '\(eventType)' } "
|
|
171
|
-
model3DComponent.wv?.fireComponentEvent(componentId: model3DComponent.id, data: data)
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private func onLonePressEnded(_: LongPressGesture.Value) {
|
|
176
|
-
print("onLonePressEnded")
|
|
177
|
-
if let model3DComponent = e.getComponent(SpatialModel3DComponent.self) {
|
|
178
|
-
let eventType = "longpress"
|
|
179
|
-
let data = "{eventType: '\(eventType)' } "
|
|
180
|
-
model3DComponent.wv?.fireComponentEvent(componentId: model3DComponent.id, data: data)
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
private func fireDragEvent(_ eventType: String, _ value: DragGesture.Value) {
|
|
185
|
-
if let model3DComponent = e.getComponent(SpatialModel3DComponent.self) {
|
|
186
|
-
let startLocation3D = value.startLocation3D
|
|
187
|
-
let translation3D = value.translation3D
|
|
188
|
-
|
|
189
|
-
let data = "{eventType: '\(eventType)', value: { translation3D : { x: \(translation3D.x), y: \(translation3D.y), z: \(translation3D.z) }, startLocation3D: { x: \(startLocation3D.x), y: \(startLocation3D.y), z: \(startLocation3D.z)} } } "
|
|
190
|
-
model3DComponent.wv?.fireComponentEvent(componentId: model3DComponent.id, data: data)
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|