@webspatial/core-sdk 1.3.0 → 1.4.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/CHANGELOG.md +41 -1
- package/dist/iife/index.d.ts +73 -31
- package/dist/iife/index.global.js +14 -14
- package/dist/iife/index.global.js.map +1 -1
- package/dist/index.d.ts +73 -31
- package/dist/index.js +182 -64
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/JSBCommand.ts +33 -0
- package/src/Spatial.ts +22 -1
- package/src/SpatialScene.ts +20 -0
- package/src/SpatializedDynamic3DElement.ts +19 -0
- package/src/SpatializedElement.ts +0 -29
- package/src/SpatializedStatic3DElement.test.ts +125 -0
- package/src/SpatializedStatic3DElement.ts +2 -0
- package/src/WebMsgCommand.ts +0 -26
- package/src/index.ts +2 -0
- package/src/jsbcommand.coverage.test.ts +0 -43
- package/src/physicalMetrics.test.ts +110 -0
- package/src/physicalMetrics.ts +101 -0
- package/src/platform-adapter/puppeteer/PuppeteerPlatform.ts +52 -52
- package/src/reality/Attachment.ts +2 -0
- package/src/reality/entity/SpatialEntity.ts +45 -24
- package/src/types/global.d.ts +7 -5
- package/src/types/types.ts +16 -2
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
CommandResultSuccess,
|
|
5
5
|
} from '../CommandResultUtils'
|
|
6
6
|
|
|
7
|
-
//
|
|
7
|
+
// add window interface for JSB call
|
|
8
8
|
declare global {
|
|
9
9
|
interface Window {
|
|
10
10
|
__handleJSBMessage: (message: string) => any
|
|
@@ -24,7 +24,7 @@ type JSBError = {
|
|
|
24
24
|
console.log('PuppeteerPlatform')
|
|
25
25
|
|
|
26
26
|
export class PuppeteerPlatform implements PlatformAbility {
|
|
27
|
-
//
|
|
27
|
+
// store iframe instance
|
|
28
28
|
private iframeRegistry: Map<string, HTMLIFrameElement> = new Map()
|
|
29
29
|
|
|
30
30
|
constructor() {}
|
|
@@ -32,7 +32,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
32
32
|
callJSB(cmd: string, msg: string): Promise<CommandResult> {
|
|
33
33
|
return new Promise(resolve => {
|
|
34
34
|
try {
|
|
35
|
-
//
|
|
35
|
+
// check __handleJSBMessage exist
|
|
36
36
|
if (window.__handleJSBMessage) {
|
|
37
37
|
try {
|
|
38
38
|
console.log(` core-sdk Puppeteer Platform: callJSB: ${cmd}::${msg}`)
|
|
@@ -45,7 +45,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
45
45
|
resolve(CommandResultFailure('500', 'JSB execution error'))
|
|
46
46
|
}
|
|
47
47
|
} else {
|
|
48
|
-
//
|
|
48
|
+
// if not exist, return default result
|
|
49
49
|
resolve(CommandResultSuccess('ok'))
|
|
50
50
|
}
|
|
51
51
|
} catch (error: unknown) {
|
|
@@ -58,7 +58,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
/**
|
|
61
|
-
*
|
|
61
|
+
* Synchronously create Spatialized2DElement to Puppeteer Runner
|
|
62
62
|
*/
|
|
63
63
|
private createSpatializedElementSync(
|
|
64
64
|
spatialId: string,
|
|
@@ -68,10 +68,10 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
68
68
|
console.log(
|
|
69
69
|
`[Puppeteer Platform] Creating spatialized element sync with id: ${spatialId}, url: ${webspatialUrl}`,
|
|
70
70
|
)
|
|
71
|
-
//
|
|
71
|
+
// directly call Puppeteer Runner method to create element
|
|
72
72
|
const win = window as any
|
|
73
73
|
if (win.__handleJSBMessage) {
|
|
74
|
-
//
|
|
74
|
+
// use simpler format to ensure JSBManager can correctly use our passed spatialId
|
|
75
75
|
const createCommand = {
|
|
76
76
|
id: spatialId,
|
|
77
77
|
url: webspatialUrl,
|
|
@@ -96,9 +96,9 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
96
96
|
)
|
|
97
97
|
return new Promise(resolve => {
|
|
98
98
|
try {
|
|
99
|
-
//
|
|
99
|
+
// create complete webspatial URL
|
|
100
100
|
const webspatialUrl = `webspatial://${command}${query ? `?${query}` : ''}`
|
|
101
|
-
//
|
|
101
|
+
// use iframe to create new window
|
|
102
102
|
const { spatialId, iframe, windowProxy } = this.createIframeWindow(
|
|
103
103
|
webspatialUrl,
|
|
104
104
|
target,
|
|
@@ -112,7 +112,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
112
112
|
console.log(
|
|
113
113
|
`[Puppeteer Platform] iframe created with spatialId: ${spatialId}`,
|
|
114
114
|
)
|
|
115
|
-
//
|
|
115
|
+
// store iframe instance
|
|
116
116
|
this.iframeRegistry.set(spatialId, iframe)
|
|
117
117
|
resolve(CommandResultSuccess({ windowProxy, id: spatialId }))
|
|
118
118
|
} catch (error) {
|
|
@@ -131,7 +131,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
131
131
|
features?: string,
|
|
132
132
|
): CommandResult {
|
|
133
133
|
try {
|
|
134
|
-
//
|
|
134
|
+
// create complete webspatial URL
|
|
135
135
|
const webspatialUrl = `webspatial://${command}${query ? `?${query}` : ''}`
|
|
136
136
|
console.log(`Calling webspatial protocol sync: ${webspatialUrl}`)
|
|
137
137
|
|
|
@@ -147,7 +147,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
147
147
|
this.createSpatializedElementSync(spatialId, webspatialUrl)
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
//
|
|
150
|
+
// store iframe instance
|
|
151
151
|
this.iframeRegistry.set(spatialId, iframe)
|
|
152
152
|
|
|
153
153
|
return CommandResultSuccess({ windowProxy, id: spatialId })
|
|
@@ -161,27 +161,27 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
161
161
|
}
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
|
-
*
|
|
164
|
+
* Synchronously create iframe-based window
|
|
165
165
|
*/
|
|
166
166
|
private createIframeWindow(url: string, target?: string, features?: string) {
|
|
167
|
-
//
|
|
167
|
+
// create iframe element
|
|
168
168
|
const iframe = document.createElement('iframe')
|
|
169
169
|
|
|
170
|
-
//
|
|
170
|
+
// set iframe attributes
|
|
171
171
|
iframe.style.border = 'none'
|
|
172
|
-
iframe.style.display = 'none'
|
|
172
|
+
iframe.style.display = 'none'
|
|
173
173
|
iframe.style.width = '100%'
|
|
174
174
|
iframe.style.height = '100%'
|
|
175
175
|
|
|
176
|
-
//
|
|
176
|
+
// set iframe id
|
|
177
177
|
const spatialId = this.generateUUID()
|
|
178
178
|
iframe.spatialId = spatialId
|
|
179
179
|
iframe.id = `spatial-iframe-${spatialId}`
|
|
180
180
|
|
|
181
|
-
//
|
|
181
|
+
// parse features parameter
|
|
182
182
|
const featuresObj = this.parseFeatures(features || '')
|
|
183
183
|
|
|
184
|
-
//
|
|
184
|
+
// set iframe styles based on features
|
|
185
185
|
if (featuresObj.width) {
|
|
186
186
|
iframe.style.width = featuresObj.width
|
|
187
187
|
}
|
|
@@ -197,36 +197,36 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
197
197
|
iframe.style.position = 'absolute'
|
|
198
198
|
}
|
|
199
199
|
|
|
200
|
-
//
|
|
200
|
+
// add iframe to DOM
|
|
201
201
|
document.body.appendChild(iframe)
|
|
202
202
|
|
|
203
|
-
//
|
|
203
|
+
// create enhanced windowProxy object
|
|
204
204
|
const windowProxy = this.createEnhancedWindowProxy(iframe, url, spatialId)
|
|
205
205
|
|
|
206
|
-
//
|
|
206
|
+
// set iframe src
|
|
207
207
|
iframe.src = 'about:blank'
|
|
208
208
|
|
|
209
209
|
console.log(
|
|
210
210
|
`PuppeteerPlatform created iframe window with spatialId: ${spatialId}, URL: ${url}`,
|
|
211
211
|
)
|
|
212
212
|
|
|
213
|
-
//
|
|
213
|
+
// initialize iframe content
|
|
214
214
|
this.initializeIframeContent(iframe, url, spatialId)
|
|
215
215
|
|
|
216
216
|
return { spatialId, iframe, windowProxy }
|
|
217
217
|
}
|
|
218
218
|
|
|
219
219
|
/**
|
|
220
|
-
*
|
|
220
|
+
* create enhanced windowProxy object
|
|
221
221
|
*/
|
|
222
222
|
private createEnhancedWindowProxy(
|
|
223
223
|
iframe: HTMLIFrameElement,
|
|
224
224
|
url: string,
|
|
225
225
|
spatialId: string,
|
|
226
226
|
) {
|
|
227
|
-
//
|
|
227
|
+
// create enhanced windowProxy object
|
|
228
228
|
return {
|
|
229
|
-
//
|
|
229
|
+
// basic properties
|
|
230
230
|
location: {
|
|
231
231
|
href: url,
|
|
232
232
|
toString: () => url,
|
|
@@ -240,25 +240,25 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
240
240
|
userAgent: `Mozilla/5.0 (WebKit) SpatialId/${spatialId}`,
|
|
241
241
|
},
|
|
242
242
|
|
|
243
|
-
//
|
|
243
|
+
// methods
|
|
244
244
|
close: () => {
|
|
245
245
|
console.log(`Closing iframe with spatialId: ${spatialId}`)
|
|
246
246
|
iframe.remove()
|
|
247
247
|
this.iframeRegistry.delete(spatialId)
|
|
248
248
|
},
|
|
249
249
|
|
|
250
|
-
//
|
|
250
|
+
// document access
|
|
251
251
|
document: iframe.contentDocument || ({} as Document),
|
|
252
252
|
contentWindow: iframe.contentWindow || ({} as Window),
|
|
253
253
|
|
|
254
|
-
//
|
|
254
|
+
// add message communication method
|
|
255
255
|
postMessage: (message: any, targetOrigin?: string) => {
|
|
256
256
|
if (iframe.contentWindow) {
|
|
257
257
|
iframe.contentWindow.postMessage(message, targetOrigin || '*')
|
|
258
258
|
}
|
|
259
259
|
},
|
|
260
260
|
|
|
261
|
-
//
|
|
261
|
+
// add event listener method
|
|
262
262
|
addEventListener: (
|
|
263
263
|
type: string,
|
|
264
264
|
listener: EventListenerOrEventListenerObject,
|
|
@@ -277,11 +277,11 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
277
277
|
}
|
|
278
278
|
},
|
|
279
279
|
|
|
280
|
-
//
|
|
280
|
+
// execute JavaScript
|
|
281
281
|
executeScript: (code: string): any => {
|
|
282
282
|
if (iframe.contentWindow) {
|
|
283
283
|
try {
|
|
284
|
-
//
|
|
284
|
+
// use type assertion and safer way to execute script
|
|
285
285
|
const win = iframe.contentWindow as any
|
|
286
286
|
return win.eval(code)
|
|
287
287
|
} catch (error) {
|
|
@@ -295,16 +295,16 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
295
295
|
return null
|
|
296
296
|
},
|
|
297
297
|
|
|
298
|
-
//
|
|
298
|
+
// get iframe reference
|
|
299
299
|
getIframe: () => iframe,
|
|
300
300
|
|
|
301
|
-
//
|
|
301
|
+
// get spatialId
|
|
302
302
|
getSpatialId: () => spatialId,
|
|
303
303
|
}
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
/**
|
|
307
|
-
*
|
|
307
|
+
* initialize iframe content
|
|
308
308
|
*/
|
|
309
309
|
private initializeIframeContent(
|
|
310
310
|
iframe: HTMLIFrameElement,
|
|
@@ -312,20 +312,20 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
312
312
|
spatialId: string,
|
|
313
313
|
): void {
|
|
314
314
|
try {
|
|
315
|
-
//
|
|
315
|
+
// wait for iframe to load
|
|
316
316
|
iframe.onload = () => {
|
|
317
317
|
try {
|
|
318
|
-
//
|
|
318
|
+
// set iframe content
|
|
319
319
|
const iframeContent = `
|
|
320
|
-
//
|
|
320
|
+
// inject communication script
|
|
321
321
|
window.webSpatialId = '${spatialId}';
|
|
322
322
|
window.SpatialId = '${spatialId}';
|
|
323
323
|
|
|
324
|
-
//
|
|
324
|
+
// override window.open to support webspatial protocol
|
|
325
325
|
const originalOpen = window.open;
|
|
326
326
|
window.open = function(url, target, features) {
|
|
327
327
|
if (url && url.startsWith('webspatial://')) {
|
|
328
|
-
//
|
|
328
|
+
// handle webspatial protocol through windowProxy
|
|
329
329
|
const windowProxy = new Proxy({}, {
|
|
330
330
|
get: function(target, prop) {
|
|
331
331
|
if (prop === 'toString') {
|
|
@@ -339,33 +339,33 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
339
339
|
return originalOpen.call(window, url, target, features);
|
|
340
340
|
};
|
|
341
341
|
|
|
342
|
-
//
|
|
342
|
+
// set navigator.userAgent to identify webspatial environment
|
|
343
343
|
Object.defineProperty(navigator, 'userAgent', {
|
|
344
344
|
value: 'WebSpatial/1.0 ' + navigator.userAgent,
|
|
345
345
|
configurable: true
|
|
346
346
|
});
|
|
347
347
|
|
|
348
|
-
//
|
|
348
|
+
// send loaded message
|
|
349
349
|
window.parent.postMessage({
|
|
350
350
|
type: 'iframe_loaded',
|
|
351
351
|
spatialId: '${spatialId}',
|
|
352
352
|
url: '${url}'
|
|
353
353
|
}, '${window.location.origin}');
|
|
354
354
|
|
|
355
|
-
//
|
|
355
|
+
// set message handler
|
|
356
356
|
window.addEventListener('message', (event) => {
|
|
357
357
|
if (event.origin !== window.parent.location.origin) return;
|
|
358
358
|
|
|
359
359
|
const data = event.data;
|
|
360
360
|
if (data && data.type === 'webspatial_command') {
|
|
361
|
-
//
|
|
361
|
+
// handle command from parent window
|
|
362
362
|
console.log('Received command in iframe from parent:', data.command);
|
|
363
|
-
//
|
|
363
|
+
// add command handling logic here
|
|
364
364
|
}
|
|
365
365
|
});
|
|
366
366
|
`
|
|
367
367
|
|
|
368
|
-
//
|
|
368
|
+
// use document.write instead of eval for security and type compliance
|
|
369
369
|
const doc = iframe.contentDocument
|
|
370
370
|
if (doc) {
|
|
371
371
|
doc.open()
|
|
@@ -400,7 +400,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
400
400
|
}
|
|
401
401
|
|
|
402
402
|
/**
|
|
403
|
-
*
|
|
403
|
+
* parse features string to object
|
|
404
404
|
*/
|
|
405
405
|
private parseFeatures(features: string): Record<string, string> {
|
|
406
406
|
const result: Record<string, string> = {}
|
|
@@ -417,7 +417,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
417
417
|
}
|
|
418
418
|
|
|
419
419
|
/**
|
|
420
|
-
*
|
|
420
|
+
* send message to iframe with specified spatialId
|
|
421
421
|
*/
|
|
422
422
|
public sendMessageToIframe(spatialId: string, message: any): boolean {
|
|
423
423
|
const iframe = this.iframeRegistry.get(spatialId)
|
|
@@ -429,7 +429,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
429
429
|
}
|
|
430
430
|
|
|
431
431
|
/**
|
|
432
|
-
*
|
|
432
|
+
* get all active iframes
|
|
433
433
|
*/
|
|
434
434
|
public getAllActiveIframes(): Array<{
|
|
435
435
|
spatialId: string
|
|
@@ -445,10 +445,10 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
445
445
|
}
|
|
446
446
|
|
|
447
447
|
/**
|
|
448
|
-
*
|
|
448
|
+
* dispose all active iframes
|
|
449
449
|
*/
|
|
450
450
|
public dispose(): void {
|
|
451
|
-
//
|
|
451
|
+
// close all iframes
|
|
452
452
|
this.iframeRegistry.forEach((iframe, spatialId) => {
|
|
453
453
|
console.log(`Disposing iframe with spatialId: ${spatialId}`)
|
|
454
454
|
iframe.remove()
|
|
@@ -456,7 +456,7 @@ export class PuppeteerPlatform implements PlatformAbility {
|
|
|
456
456
|
this.iframeRegistry.clear()
|
|
457
457
|
}
|
|
458
458
|
|
|
459
|
-
//
|
|
459
|
+
// generate UUID function
|
|
460
460
|
private generateUUID(): string {
|
|
461
461
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(
|
|
462
462
|
/[xy]/g,
|
|
@@ -2,6 +2,7 @@ import { SpatialObject } from '../SpatialObject'
|
|
|
2
2
|
import {
|
|
3
3
|
CreateAttachmentEntityCommand,
|
|
4
4
|
UpdateAttachmentEntityCommand,
|
|
5
|
+
InitializeAttachmentCommand,
|
|
5
6
|
} from '../JSBCommand'
|
|
6
7
|
import {
|
|
7
8
|
AttachmentEntityOptions,
|
|
@@ -41,5 +42,6 @@ export async function createAttachmentEntity(
|
|
|
41
42
|
throw new Error('createAttachmentEntity failed: ' + result?.errorMessage)
|
|
42
43
|
}
|
|
43
44
|
const { id, windowProxy } = result.data!
|
|
45
|
+
await new InitializeAttachmentCommand(id, options).execute()
|
|
44
46
|
return new Attachment(id, windowProxy, options)
|
|
45
47
|
}
|
|
@@ -23,16 +23,16 @@ import { SpatialComponent } from '../component/SpatialComponent'
|
|
|
23
23
|
import { SpatialWebEvent } from '../../SpatialWebEvent'
|
|
24
24
|
import { createSpatialEvent } from '../../SpatialWebEventCreator'
|
|
25
25
|
import {
|
|
26
|
-
CubeInfoMsg,
|
|
27
26
|
ObjectDestroyMsg,
|
|
28
27
|
SpatialDragEndMsg,
|
|
29
28
|
SpatialDragMsg,
|
|
29
|
+
SpatialDragStartMsg,
|
|
30
|
+
SpatialMagnifyEndMsg,
|
|
30
31
|
SpatialMagnifyMsg,
|
|
31
32
|
SpatialRotateEndMsg,
|
|
32
33
|
SpatialRotateMsg,
|
|
33
34
|
SpatialTapMsg,
|
|
34
35
|
SpatialWebMsgType,
|
|
35
|
-
TransformMsg,
|
|
36
36
|
} from '../../WebMsgCommand'
|
|
37
37
|
|
|
38
38
|
export class SpatialEntity extends SpatialObject {
|
|
@@ -43,6 +43,31 @@ export class SpatialEntity extends SpatialObject {
|
|
|
43
43
|
events: Record<string, (data: any) => void> = {}
|
|
44
44
|
children: SpatialEntity[] = []
|
|
45
45
|
parent: SpatialEntityOrReality | null = null
|
|
46
|
+
private _enableInput: boolean = false
|
|
47
|
+
|
|
48
|
+
get enableInput(): boolean {
|
|
49
|
+
return this._enableInput
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
set enableInput(value: boolean) {
|
|
53
|
+
// Why enabling only 'spatialtap' makes the entity interactive:
|
|
54
|
+
// - On the native (Swift/RealityKit) side, SpatialEntity.updateGesture(type, isEnable)
|
|
55
|
+
// toggles per-gesture flags. Then enableInteractive = enableTap || enableRotate || enableDrag || enableMagnify.
|
|
56
|
+
// - As soon as any gesture (e.g., 'spatialtap') is enabled, enableInteractive becomes true and
|
|
57
|
+
// InputTargetComponent is attached, making the entity targetable by targetedToAnyEntity().
|
|
58
|
+
// - The view layer forwards hit gestures to the web, so enabling 'spatialtap' is sufficient to
|
|
59
|
+
// make the entity targetable; enable additional gestures only when needed.
|
|
60
|
+
if (this._enableInput === value) return
|
|
61
|
+
this._enableInput = value
|
|
62
|
+
void this.updateEntityEvent('spatialtap', value).catch(err => {
|
|
63
|
+
console.error('enableInput updateEntityEvent failed', 'spatialtap', err)
|
|
64
|
+
// Roll back local flag if the native toggle fails to keep web/native states consistent.
|
|
65
|
+
// Otherwise, the web side would think the entity is interactive while RealityKit is not.
|
|
66
|
+
if (this._enableInput === value) {
|
|
67
|
+
this._enableInput = !value
|
|
68
|
+
}
|
|
69
|
+
})
|
|
70
|
+
}
|
|
46
71
|
constructor(
|
|
47
72
|
id: string,
|
|
48
73
|
public userData?: SpatialEntityUserData,
|
|
@@ -123,13 +148,15 @@ export class SpatialEntity extends SpatialObject {
|
|
|
123
148
|
return new UpdateEntityEventCommand(this, eventName, isEnable).execute()
|
|
124
149
|
}
|
|
125
150
|
private onReceiveEvent = (
|
|
126
|
-
data:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
151
|
+
data:
|
|
152
|
+
| SpatialTapMsg
|
|
153
|
+
| SpatialDragStartMsg
|
|
154
|
+
| SpatialDragMsg
|
|
155
|
+
| SpatialDragEndMsg
|
|
156
|
+
| SpatialMagnifyMsg
|
|
157
|
+
| SpatialMagnifyEndMsg
|
|
158
|
+
| SpatialRotateMsg
|
|
159
|
+
| SpatialRotateEndMsg
|
|
133
160
|
| ObjectDestroyMsg,
|
|
134
161
|
) => {
|
|
135
162
|
// console.log('SpatialEntityEvent', data)
|
|
@@ -139,27 +166,21 @@ export class SpatialEntity extends SpatialObject {
|
|
|
139
166
|
}
|
|
140
167
|
// tap
|
|
141
168
|
else if (type === SpatialWebMsgType.spatialtap) {
|
|
142
|
-
const evt = createSpatialEvent(
|
|
143
|
-
SpatialWebMsgType.spatialtap,
|
|
144
|
-
(data as SpatialTapMsg).detail,
|
|
145
|
-
)
|
|
169
|
+
const evt = createSpatialEvent(SpatialWebMsgType.spatialtap, data.detail)
|
|
146
170
|
this.dispatchEvent(evt)
|
|
147
171
|
} else if (type === SpatialWebMsgType.spatialdragstart) {
|
|
148
172
|
const evt = createSpatialEvent(
|
|
149
173
|
SpatialWebMsgType.spatialdragstart,
|
|
150
|
-
|
|
174
|
+
data.detail,
|
|
151
175
|
)
|
|
152
176
|
this.dispatchEvent(evt)
|
|
153
177
|
} else if (type === SpatialWebMsgType.spatialdrag) {
|
|
154
|
-
const evt = createSpatialEvent(
|
|
155
|
-
SpatialWebMsgType.spatialdrag,
|
|
156
|
-
(data as SpatialDragMsg).detail,
|
|
157
|
-
)
|
|
178
|
+
const evt = createSpatialEvent(SpatialWebMsgType.spatialdrag, data.detail)
|
|
158
179
|
this.dispatchEvent(evt)
|
|
159
180
|
} else if (type === SpatialWebMsgType.spatialdragend) {
|
|
160
181
|
const evt = createSpatialEvent(
|
|
161
182
|
SpatialWebMsgType.spatialdragend,
|
|
162
|
-
|
|
183
|
+
data.detail,
|
|
163
184
|
)
|
|
164
185
|
this.dispatchEvent(evt)
|
|
165
186
|
}
|
|
@@ -167,13 +188,13 @@ export class SpatialEntity extends SpatialObject {
|
|
|
167
188
|
else if (type === SpatialWebMsgType.spatialrotate) {
|
|
168
189
|
const evt = createSpatialEvent(
|
|
169
190
|
SpatialWebMsgType.spatialrotate,
|
|
170
|
-
|
|
191
|
+
data.detail,
|
|
171
192
|
)
|
|
172
193
|
this.dispatchEvent(evt)
|
|
173
194
|
} else if (type === SpatialWebMsgType.spatialrotateend) {
|
|
174
195
|
const evt = createSpatialEvent(
|
|
175
196
|
SpatialWebMsgType.spatialrotateend,
|
|
176
|
-
|
|
197
|
+
data.detail,
|
|
177
198
|
)
|
|
178
199
|
this.dispatchEvent(evt)
|
|
179
200
|
}
|
|
@@ -181,13 +202,13 @@ export class SpatialEntity extends SpatialObject {
|
|
|
181
202
|
else if (type === SpatialWebMsgType.spatialmagnify) {
|
|
182
203
|
const evt = createSpatialEvent(
|
|
183
204
|
SpatialWebMsgType.spatialmagnify,
|
|
184
|
-
|
|
205
|
+
data.detail,
|
|
185
206
|
)
|
|
186
207
|
this.dispatchEvent(evt)
|
|
187
208
|
} else if (type === SpatialWebMsgType.spatialmagnifyend) {
|
|
188
209
|
const evt = createSpatialEvent(
|
|
189
210
|
SpatialWebMsgType.spatialmagnifyend,
|
|
190
|
-
|
|
211
|
+
data.detail,
|
|
191
212
|
)
|
|
192
213
|
this.dispatchEvent(evt)
|
|
193
214
|
}
|
|
@@ -200,7 +221,7 @@ export class SpatialEntity extends SpatialObject {
|
|
|
200
221
|
}
|
|
201
222
|
this.events[evt.type]?.(evt)
|
|
202
223
|
if (evt.bubbles && !evt.cancelBubble) {
|
|
203
|
-
if (this.parent
|
|
224
|
+
if (this.parent) {
|
|
204
225
|
this.parent.dispatchEvent(evt)
|
|
205
226
|
}
|
|
206
227
|
}
|
package/src/types/global.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { PhysicalMetricsValueShape } from '../physicalMetrics'
|
|
2
|
+
|
|
1
3
|
declare global {
|
|
2
4
|
declare const __WEBSPATIAL_CORE_SDK_VERSION__: string
|
|
3
5
|
|
|
@@ -28,16 +30,16 @@ declare global {
|
|
|
28
30
|
'natvie-version'?: string
|
|
29
31
|
'react-sdk-version'?: string
|
|
30
32
|
'core-sdk-version'?: string
|
|
33
|
+
physicalMetrics?: PhysicalMetricsValueShape
|
|
31
34
|
}
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
|
|
36
|
+
xrInnerDepth: number
|
|
37
|
+
xrOuterDepth: number
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
interface HTMLElement {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
getBoundingClientCube: () => CubeInfo | undefined
|
|
41
|
+
xrOffsetBack: number
|
|
42
|
+
xrClientDepth: number
|
|
41
43
|
}
|
|
42
44
|
}
|
|
43
45
|
|
package/src/types/types.ts
CHANGED
|
@@ -80,6 +80,11 @@ export interface SpatializedElementProperties {
|
|
|
80
80
|
enableRotateEndGesture: boolean
|
|
81
81
|
enableMagnifyGesture: boolean
|
|
82
82
|
enableMagnifyEndGesture: boolean
|
|
83
|
+
/**
|
|
84
|
+
* Optional world-space axis for spatial rotate gesture. Omitted or zero vector
|
|
85
|
+
* means unconstrained rotation (platform default).
|
|
86
|
+
*/
|
|
87
|
+
rotateConstrainedToAxis?: Vec3
|
|
83
88
|
}
|
|
84
89
|
|
|
85
90
|
export interface Spatialized2DElementProperties
|
|
@@ -115,6 +120,16 @@ export interface SpatialSceneCreationOptions {
|
|
|
115
120
|
baseplateVisibility?: BaseplateVisibilityType
|
|
116
121
|
}
|
|
117
122
|
|
|
123
|
+
export type SpatialEntityEventType =
|
|
124
|
+
| 'spatialtap'
|
|
125
|
+
| 'spatialdragstart'
|
|
126
|
+
| 'spatialdrag'
|
|
127
|
+
| 'spatialdragend'
|
|
128
|
+
| 'spatialrotate'
|
|
129
|
+
| 'spatialrotateend'
|
|
130
|
+
| 'spatialmagnify'
|
|
131
|
+
| 'spatialmagnifyend'
|
|
132
|
+
|
|
118
133
|
export const BaseplateVisibilityValues = [
|
|
119
134
|
'automatic',
|
|
120
135
|
'visible',
|
|
@@ -186,8 +201,6 @@ export interface SpatialEntityProperties {
|
|
|
186
201
|
scale: Vec3
|
|
187
202
|
}
|
|
188
203
|
|
|
189
|
-
export type SpatialEntityEventType = 'spatialtap' //| 'drag' | 'rotate' | 'scale'
|
|
190
|
-
|
|
191
204
|
export type SpatialGeometryType =
|
|
192
205
|
| 'BoxGeometry'
|
|
193
206
|
| 'PlaneGeometry'
|
|
@@ -391,6 +404,7 @@ export interface AttachmentEntityOptions {
|
|
|
391
404
|
parentEntityId: string
|
|
392
405
|
position?: [number, number, number]
|
|
393
406
|
size: { width: number; height: number }
|
|
407
|
+
ownerViewId: string
|
|
394
408
|
}
|
|
395
409
|
|
|
396
410
|
export interface AttachmentEntityUpdateOptions {
|