@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.
Files changed (92) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/lib/Cli.js +1 -1
  3. package/dist/lib/cmds/build.d.ts +1 -1
  4. package/dist/lib/cmds/build.js +1 -1
  5. package/dist/lib/cmds/check.js +1 -1
  6. package/dist/lib/cmds/help.js +1 -1
  7. package/dist/lib/cmds/version.js +1 -1
  8. package/dist/lib/pwa/config.js +1 -1
  9. package/dist/lib/pwa/index.js +1 -1
  10. package/dist/lib/pwa/validate.js +1 -1
  11. package/dist/lib/resource/file.js +1 -1
  12. package/dist/lib/resource/imageHelper.js +1 -1
  13. package/dist/lib/resource/index.d.ts +10 -3
  14. package/dist/lib/resource/index.js +1 -1
  15. package/dist/lib/resource/load.js +1 -1
  16. package/dist/lib/utils/CustomError.js +1 -1
  17. package/dist/lib/utils/FetchUtils-1.js +1 -1
  18. package/dist/lib/utils/Log.js +1 -1
  19. package/dist/lib/utils/fetch.js +1 -1
  20. package/dist/lib/utils/messages.js +1 -1
  21. package/dist/lib/utils/utils.d.ts +9 -0
  22. package/dist/lib/utils/utils.js +1 -1
  23. package/dist/lib/xcode/index.js +1 -1
  24. package/dist/lib/xcode/manifestSwiftTemplate.d.ts +1 -1
  25. package/dist/lib/xcode/manifestSwiftTemplate.js +1 -1
  26. package/dist/lib/xcode/xcodebuild.js +1 -1
  27. package/dist/lib/xcode/xcodeproject.js +1 -1
  28. package/dist/lib/xcode/xcrun.js +1 -1
  29. package/package.json +3 -2
  30. package/template/visionOSApp/Packages/RealityKitContent/.build/workspace-state.json +0 -7
  31. package/template/visionOSApp/Packages/RealityKitContent/.swiftpm/xcode/xcuserdata/bytedance.xcuserdatad/xcschemes/xcschememanagement.plist +0 -14
  32. package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/ProjectData/main.json +0 -11
  33. package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/SceneMetadataList.json +0 -112
  34. package/template/visionOSApp/Packages/RealityKitContent/Package.realitycomposerpro/WorkspaceData/Settings.rcprojectdata +0 -17
  35. package/template/visionOSApp/Packages/RealityKitContent/Package.swift +0 -27
  36. package/template/visionOSApp/Packages/RealityKitContent/README.md +0 -3
  37. package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Immersive.usda +0 -50
  38. package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Materials/GridMaterial.usda +0 -216
  39. package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.rkassets/Scene.usda +0 -59
  40. package/template/visionOSApp/Packages/RealityKitContent/Sources/RealityKitContent/RealityKitContent.swift +0 -4
  41. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Content.imageset/Contents.json +0 -12
  42. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Back.solidimagestacklayer/Contents.json +0 -6
  43. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Contents.json +0 -17
  44. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Content.imageset/Contents.json +0 -12
  45. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Front.solidimagestacklayer/Contents.json +0 -6
  46. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Content.imageset/Contents.json +0 -12
  47. package/template/visionOSApp/web-spatial/Assets.xcassets/AppIcon.solidimagestack/Middle.solidimagestacklayer/Contents.json +0 -6
  48. package/template/visionOSApp/web-spatial/Assets.xcassets/Contents.json +0 -6
  49. package/template/visionOSApp/web-spatial/Info.plist +0 -33
  50. package/template/visionOSApp/web-spatial/Preview Content/Preview Assets.xcassets/Contents.json +0 -6
  51. package/template/visionOSApp/web-spatial/libs/EventEmitter.swift +0 -32
  52. package/template/visionOSApp/web-spatial/libs/SpatialComponent.swift +0 -31
  53. package/template/visionOSApp/web-spatial/libs/SpatialEntity.swift +0 -179
  54. package/template/visionOSApp/web-spatial/libs/SpatialInputComponent.swift +0 -26
  55. package/template/visionOSApp/web-spatial/libs/SpatialMeshResource.swift +0 -19
  56. package/template/visionOSApp/web-spatial/libs/SpatialModel3DComponent.swift +0 -51
  57. package/template/visionOSApp/web-spatial/libs/SpatialModelComponent.swift +0 -32
  58. package/template/visionOSApp/web-spatial/libs/SpatialObject.swift +0 -144
  59. package/template/visionOSApp/web-spatial/libs/SpatialPhysicallyBasedMaterial.swift +0 -19
  60. package/template/visionOSApp/web-spatial/libs/SpatialViewComponent.swift +0 -15
  61. package/template/visionOSApp/web-spatial/libs/SpatialWindowComponent.swift +0 -420
  62. package/template/visionOSApp/web-spatial/libs/SpatialWindowContainer.swift +0 -149
  63. package/template/visionOSApp/web-spatial/libs/Utils/CommandManager.swift +0 -800
  64. package/template/visionOSApp/web-spatial/libs/Utils/Logger.swift +0 -36
  65. package/template/visionOSApp/web-spatial/libs/Utils/SceneManager.swift +0 -108
  66. package/template/visionOSApp/web-spatial/libs/Utils/WindowContainerMgr.swift +0 -113
  67. package/template/visionOSApp/web-spatial/libs/json/JsonParser.swift +0 -52
  68. package/template/visionOSApp/web-spatial/libs/uiKitDelegate/Window.swift +0 -34
  69. package/template/visionOSApp/web-spatial/libs/webView/UpdateSystem.swift +0 -33
  70. package/template/visionOSApp/web-spatial/libs/webView/backend/NativeWebView.swift +0 -319
  71. package/template/visionOSApp/web-spatial/libs/webView/manifest.swift +0 -92
  72. package/template/visionOSApp/web-spatial/static-web/index.html +0 -9
  73. package/template/visionOSApp/web-spatial/views/HideViewModifier.swift +0 -17
  74. package/template/visionOSApp/web-spatial/views/ImmersiveView.swift +0 -24
  75. package/template/visionOSApp/web-spatial/views/LoadingView.swift +0 -25
  76. package/template/visionOSApp/web-spatial/views/MaterialWithBorderCornerModifier.swift +0 -82
  77. package/template/visionOSApp/web-spatial/views/OpenDismissHandlerUI.swift +0 -52
  78. package/template/visionOSApp/web-spatial/views/PlainWindowContainerView.swift +0 -84
  79. package/template/visionOSApp/web-spatial/views/SpatialModel3DView.swift +0 -193
  80. package/template/visionOSApp/web-spatial/views/SpatialViewUI.swift +0 -168
  81. package/template/visionOSApp/web-spatial/views/SpatialWebViewUI.swift +0 -186
  82. package/template/visionOSApp/web-spatial/views/VolumetricWindowContainerView.swift +0 -38
  83. package/template/visionOSApp/web-spatial/views/ui/NavView.swift +0 -125
  84. package/template/visionOSApp/web-spatial/web_spatialApp.swift +0 -158
  85. package/template/visionOSApp/web-spatial.xcodeproj/project.pbxproj +0 -686
  86. package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
  87. package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
  88. package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +0 -5
  89. package/template/visionOSApp/web-spatial.xcodeproj/project.xcworkspace/xcuserdata/bytedance.xcuserdatad/WorkspaceSettings.xcsettings +0 -14
  90. package/template/visionOSApp/web-spatial.xcodeproj/xcshareddata/xcschemes/web-spatial.xcscheme +0 -115
  91. package/template/visionOSApp/web-spatial.xcodeproj/xcuserdata/bytedance.xcuserdatad/xcschemes/xcschememanagement.plist +0 -27
  92. 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,9 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <meta charset="UTF-8">
4
- <title>WebSpatial</title>
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <body>
7
- <div>Hello WebSpatial!</div>
8
- </body>
9
- </html>
@@ -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
- }