Skip to content

Commit b418e74

Browse files
fix(view): fixed ViewService subview poses
Moved DOM setup into ArgonSystem class, allowing ViewService to be used by local realities (using a child dependency injection container).
1 parent 6f94577 commit b418e74

File tree

6 files changed

+186
-128
lines changed

6 files changed

+186
-128
lines changed

src/argon.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ export declare class ArgonSystem {
6969
*/
7070
static instance?: ArgonSystem;
7171
constructor(container: DI.Container, entity: EntityService, context: ContextService, device: DeviceService, focus: FocusService, reality: RealityService, session: SessionService, view: ViewService, visibility: VisibilityService, vuforia: VuforiaService, permission: PermissionService);
72+
private _setupDOM();
73+
readonly suggestedPixelRatio: number;
7274
_provider: ArgonSystemProvider;
7375
readonly provider: ArgonSystemProvider;
7476
readonly updateEvent: Event<any>;
@@ -80,8 +82,9 @@ export declare class ArgonSystem {
8082
export declare class ArgonConfigurationManager {
8183
configuration: Configuration;
8284
container: DI.Container;
85+
elementOrSelector: HTMLElement | string | null;
8386
static configure(configurationManager: ArgonConfigurationManager): void;
84-
constructor(configuration: Configuration, container?: DI.Container);
87+
constructor(configuration: Configuration, container?: DI.Container, elementOrSelector?: HTMLElement | string | null);
8588
standardConfiguration(): void;
8689
defaultConnect(): void;
8790
defaultUI(): void;

src/argon.ts

Lines changed: 121 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,14 @@ import {
1515

1616
import { Configuration, Role } from './common'
1717
import { DefaultUIService } from './ui'
18-
import { Event } from './utils'
18+
import { Event, isIOS, getEventSynthesizier, createEventForwarder, hasNativeWebVRImplementation } from './utils'
1919

2020
import { EntityService, EntityServiceProvider } from './entity'
2121
import { ContextService, ContextServiceProvider } from './context'
2222
import { FocusService, FocusServiceProvider } from './focus'
2323
import { DeviceService, DeviceServiceProvider } from './device'
2424
import { RealityService, RealityServiceProvider } from './reality'
25-
import { ViewService, ViewServiceProvider, ViewElement } from './view'
25+
import { ViewService, ViewServiceProvider, ViewItems, ViewportMode } from './view'
2626
import { VisibilityService, VisibilityServiceProvider } from './visibility'
2727
import { VuforiaService, VuforiaServiceProvider } from './vuforia'
2828
import { PermissionService, PermissionServiceProvider } from './permission'
@@ -101,10 +101,102 @@ export class ArgonSystem {
101101

102102
if (this.container.hasResolver(ArgonSystemProvider))
103103
this._provider = this.container.get(ArgonSystemProvider);
104+
105+
this._setupDOM();
104106

105107
this.session.connect();
106108
}
107109

110+
private _setupDOM() {
111+
const viewItems:ViewItems = this.container.get(ViewItems);
112+
const element = viewItems.element;
113+
114+
if (element && typeof document !== 'undefined' && document.createElement) {
115+
116+
element.classList.add('argon-view');
117+
118+
// prevent pinch-zoom of the page in ios 10.
119+
if (isIOS) {
120+
const touchMoveListener = (event) => {
121+
if (event.touches.length > 1)
122+
event.preventDefault();
123+
}
124+
element.addEventListener('touchmove', touchMoveListener, true);
125+
this.session.manager.closeEvent.addEventListener(()=>{
126+
element.removeEventListener('touchmove', touchMoveListener)
127+
});
128+
}
129+
130+
// add/remove document-level css classes
131+
this.focus.focusEvent.addEventListener(() => {
132+
document.documentElement.classList.remove('argon-no-focus');
133+
document.documentElement.classList.remove('argon-blur');
134+
document.documentElement.classList.add('argon-focus');
135+
});
136+
137+
this.focus.blurEvent.addEventListener(() => {
138+
document.documentElement.classList.remove('argon-focus');
139+
document.documentElement.classList.add('argon-blur');
140+
document.documentElement.classList.add('argon-no-focus');
141+
});
142+
143+
this.view.viewportModeChangeEvent.addEventListener((mode)=>{
144+
switch (mode) {
145+
case ViewportMode.EMBEDDED:
146+
document.documentElement.classList.remove('argon-immersive');
147+
break;
148+
case ViewportMode.IMMERSIVE:
149+
document.documentElement.classList.add('argon-immersive');
150+
break;
151+
}
152+
});
153+
154+
// Setup event forwarding / synthesizing
155+
if (this.session.isRealityViewer) {
156+
this.session.manager.on['ar.view.uievent'] = getEventSynthesizier()!;
157+
} else {
158+
createEventForwarder(this.view, (event)=>{
159+
if (this.session.manager.isConnected && this.session.manager.version[0] >= 1)
160+
this.session.manager.send('ar.view.forwardUIEvent', event);
161+
});
162+
this.view._watchEmbeddedViewport();
163+
}
164+
165+
this.context.renderEvent.addEventListener(()=>{
166+
if (this.view.autoStyleLayerElements) {
167+
const layers = this.view.layers;
168+
if (!layers) return;
169+
170+
const viewport = this.view.viewport;
171+
let zIndex = -layers.length;
172+
for (const layer of layers) {
173+
const layerStyle = layer.source.style;
174+
layerStyle.position = 'absolute';
175+
layerStyle.left = viewport.x + 'px';
176+
layerStyle.bottom = viewport.y + 'px';
177+
layerStyle.width = viewport.width + 'px';
178+
layerStyle.height = viewport.height + 'px';
179+
layerStyle.zIndex = '' + zIndex;
180+
zIndex++;
181+
}
182+
}
183+
});
184+
185+
if (!this.session.isRealityAugmenter) {
186+
this.view.viewportChangeEvent.addEventListener((viewport)=>{
187+
if (this.view.element && this.view.autoLayoutImmersiveMode &&
188+
this.view.viewportMode === ViewportMode.IMMERSIVE) {
189+
const elementStyle = this.view.element.style;
190+
elementStyle.position = 'fixed';
191+
elementStyle.left = viewport.x + 'px';
192+
elementStyle.bottom = viewport.y + 'px';
193+
elementStyle.width = viewport.width + 'px';
194+
elementStyle.height = viewport.height + 'px';
195+
}
196+
})
197+
}
198+
}
199+
}
108200
public _provider:ArgonSystemProvider;
109201
public get provider() {
110202
this.session.ensureIsRealityManager();
@@ -145,13 +237,39 @@ export class ArgonConfigurationManager {
145237

146238
constructor(
147239
public configuration:Configuration,
148-
public container:DI.Container = new DI.Container
240+
public container:DI.Container = new DI.Container,
241+
public elementOrSelector?:HTMLElement|string|null,
149242
) {
150243
container.registerInstance(Configuration, configuration);
151244

152245
if (Role.isRealityManager(configuration.role))
153246
container.registerSingleton(ArgonSystemProvider);
154247

248+
let element = elementOrSelector;
249+
if (!element || typeof element === 'string') {
250+
if (typeof document !== 'undefined') {
251+
const selector = element;
252+
element = selector ? <HTMLElement>document.querySelector(selector) : undefined;
253+
if (!element && !selector) {
254+
element = document.querySelector('#argon') as HTMLElement;
255+
if (!element) {
256+
element = document.createElement('div');
257+
element.id = 'argon';
258+
document.body.appendChild(element);
259+
}
260+
} else if (!element) {
261+
throw new Error('Unable to find element with selector: ' + selector);
262+
}
263+
} else {
264+
console.warn('No DOM environment is available');
265+
element = undefined;
266+
}
267+
}
268+
269+
const viewItems = new ViewItems();
270+
viewItems.element = element;
271+
container.registerInstance(ViewItems, viewItems);
272+
155273
ArgonConfigurationManager.configure(this);
156274
}
157275

@@ -254,7 +372,6 @@ export function init(
254372
}
255373

256374
if (!dependencyInjectionContainer) dependencyInjectionContainer = new DI.Container();
257-
dependencyInjectionContainer.registerInstance(ViewElement, element || null);
258375

259376
return new ArgonConfigurationManager(configuration, dependencyInjectionContainer).container.get(ArgonSystem);
260377
}

src/device.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -677,11 +677,12 @@ export class DeviceService {
677677

678678
protected onRequestPresentHMD() : Promise<void> {
679679
if (this._vrDisplay) {
680-
const element = this.viewService.element;
680+
const element = this.viewService.element!;
681+
const viewLayers = this.viewService.layers;
681682
const layers:VRLayer&{}[] =
682683
[{
683684
source:
684-
this.viewService.layers[0] && this.viewService.layers[0].source ||
685+
viewLayers && viewLayers[0] && viewLayers[0].source ||
685686
element.querySelector('canvas') ||
686687
<HTMLCanvasElement>element.lastElementChild
687688
}];

src/reality-viewers/empty.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export class EmptyRealityViewer extends RealityViewer {
157157
const childDeviceService = child.get(DeviceService) as DeviceService;
158158
const childSessionService = child.get(SessionService) as SessionService;
159159
const childRealityService = child.get(RealityService) as RealityService;
160+
const childViewService = child.get(ViewService) as ViewService;
160161

161162
// the child device service should *not* submit frames to the vrdisplay.
162163
childDeviceService.autoSubmitFrame = false;
@@ -238,7 +239,7 @@ export class EmptyRealityViewer extends RealityViewer {
238239
// provide fov controls
239240
if (!childDeviceService.strict) {
240241
decomposePerspectiveProjectionMatrix(subviews[0].projectionMatrix, scratchFrustum);
241-
scratchFrustum.fov = this.viewService.subviews[0] && this.viewService.subviews[0].frustum.fov || CesiumMath.PI_OVER_THREE;
242+
scratchFrustum.fov = childViewService.subviews[0] && childViewService.subviews[0].frustum.fov || CesiumMath.PI_OVER_THREE;
242243

243244
if (aggregator && aggregator.isMoving(CameraEventType.WHEEL)) {
244245
const wheelMovement = aggregator.getMovement(CameraEventType.WHEEL);

src/view.d.ts

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,19 @@ export declare const enum ViewportMode {
2323
PAGE = 0,
2424
IMMERSIVE = 1,
2525
}
26-
export declare abstract class ViewElement {
26+
export declare class ViewItems {
27+
element?: HTMLElement;
28+
layers?: {
29+
source: HTMLElement;
30+
}[];
2731
}
2832
/**
2933
* Manages the view state
3034
*/
3135
export declare class ViewService {
3236
private sessionService;
3337
private focusService;
38+
private viewItems;
3439
/**
3540
* UI events that occur within this view. To handle an event (and prevent it from
3641
* being forwarded to another layer) call event.stopImmediatePropagation().
@@ -81,21 +86,22 @@ export declare class ViewService {
8186
* Automatically publish the viewport of the element during PresentationMode.EMBEDDED
8287
*/
8388
autoPublishEmbeddedMode: boolean;
84-
/**
85-
* The DOM element associated with this viewport
86-
*/
87-
element: HTMLElement;
88-
constructor(sessionService: SessionService, focusService: FocusService, elementOrSelector?: Element | string | null);
89-
private _layers;
89+
constructor(sessionService: SessionService, focusService: FocusService, viewItems: ViewItems);
9090
setLayers(layers: {
9191
source: HTMLElement;
9292
}[]): void;
93+
/**
94+
* The DOM element associated with this view
95+
*/
96+
readonly element: HTMLElement | undefined;
97+
/**
98+
* The layers composing this view.
99+
*/
93100
readonly layers: {
94101
source: HTMLElement;
95-
}[];
102+
}[] | undefined;
96103
private _currentViewportJSON;
97104
private _subviews;
98-
private _subviewPose;
99105
private _subviewFrustum;
100106
readonly subviews: Subview[];
101107
/**
@@ -115,7 +121,10 @@ export declare class ViewService {
115121
private _updateViewport(viewport);
116122
sendUIEventToSession(uievent: UIEvent, session?: SessionPort): void;
117123
private _embeddedViewport;
118-
private _watchEmbeddedViewport();
124+
/**
125+
* @private
126+
*/
127+
_watchEmbeddedViewport(): void;
119128
}
120129
export declare class ViewServiceProvider {
121130
private sessionService;

0 commit comments

Comments
 (0)