@@ -91,11 +91,11 @@ async function initCesium(): Promise<any> {
9191 // Disable Ion-dependent features
9292 geocoder : false ,
9393 baseLayerPicker : false ,
94- // Simplify UI
94+ // Simplify UI - hide all controls
9595 animation : false ,
9696 timeline : false ,
97- homeButton : true ,
98- sceneModePicker : true ,
97+ homeButton : false ,
98+ sceneModePicker : false ,
9999 navigationHelpButton : false ,
100100 fullscreenButton : false ,
101101 // Disable terrain (requires Ion)
@@ -107,6 +107,8 @@ async function initCesium(): Promise<any> {
107107 alpha : true ,
108108 } ,
109109 } ,
110+ // Use full device pixel ratio for sharp rendering on high-DPI displays
111+ useBrowserRecommendedResolution : false ,
110112 } ) ;
111113 log . info ( "Viewer created" ) ;
112114
@@ -245,21 +247,6 @@ function flyToBoundingBox(
245247 } ) ;
246248}
247249
248- /**
249- * Update the label display
250- */
251- function setLabel ( text : string | undefined ) : void {
252- const labelEl = document . getElementById ( "label" ) ;
253- if ( labelEl ) {
254- if ( text ) {
255- labelEl . textContent = text ;
256- labelEl . style . display = "block" ;
257- } else {
258- labelEl . style . display = "none" ;
259- }
260- }
261- }
262-
263250/**
264251 * Hide the loading indicator
265252 */
@@ -270,13 +257,86 @@ function hideLoading(): void {
270257 }
271258}
272259
260+ // Preferred height for inline mode (px)
261+ const PREFERRED_INLINE_HEIGHT = 400 ;
262+
263+ // Current display mode
264+ let currentDisplayMode : "inline" | "fullscreen" | "pip" = "inline" ;
265+
273266// Create App instance with tool capabilities
267+ // autoResize: false - we manually send size since map fills its container
274268const app = new App (
275269 { name : "CesiumJS Globe" , version : "1.0.0" } ,
276270 { tools : { listChanged : true } } ,
277- { autoResize : false } , // Cesium handles its own sizing
271+ { autoResize : false } ,
278272) ;
279273
274+ /**
275+ * Update fullscreen button visibility and icon based on current state
276+ */
277+ function updateFullscreenButton ( ) : void {
278+ const btn = document . getElementById ( "fullscreen-btn" ) ;
279+ const expandIcon = document . getElementById ( "expand-icon" ) ;
280+ const compressIcon = document . getElementById ( "compress-icon" ) ;
281+ if ( ! btn || ! expandIcon || ! compressIcon ) return ;
282+
283+ // Check if fullscreen is available from host
284+ const context = app . getHostContext ( ) ;
285+ const availableModes = context ?. availableDisplayModes ?? [ "inline" ] ;
286+ const canFullscreen = availableModes . includes ( "fullscreen" ) ;
287+
288+ // Show button only if fullscreen is available
289+ btn . style . display = canFullscreen ? "flex" : "none" ;
290+
291+ // Toggle icons based on current mode
292+ const isFullscreen = currentDisplayMode === "fullscreen" ;
293+ expandIcon . style . display = isFullscreen ? "none" : "block" ;
294+ compressIcon . style . display = isFullscreen ? "block" : "none" ;
295+ btn . title = isFullscreen ? "Exit fullscreen" : "Enter fullscreen" ;
296+ }
297+
298+ /**
299+ * Request display mode change from host
300+ */
301+ async function toggleFullscreen ( ) : Promise < void > {
302+ const targetMode =
303+ currentDisplayMode === "fullscreen" ? "inline" : "fullscreen" ;
304+ log . info ( "Requesting display mode:" , targetMode ) ;
305+
306+ try {
307+ const result = await app . requestDisplayMode ( { mode : targetMode } ) ;
308+ log . info ( "Display mode result:" , result . mode ) ;
309+ // Note: actual mode change will come via onhostcontextchanged
310+ } catch ( error ) {
311+ log . error ( "Failed to change display mode:" , error ) ;
312+ }
313+ }
314+
315+ /**
316+ * Handle display mode changes - resize Cesium and update UI
317+ */
318+ function handleDisplayModeChange (
319+ newMode : "inline" | "fullscreen" | "pip" ,
320+ ) : void {
321+ if ( newMode === currentDisplayMode ) return ;
322+
323+ log . info ( "Display mode changed:" , currentDisplayMode , "->" , newMode ) ;
324+ currentDisplayMode = newMode ;
325+
326+ // Update button state
327+ updateFullscreenButton ( ) ;
328+
329+ // Tell Cesium to resize to new container dimensions
330+ if ( viewer ) {
331+ // Small delay to let the host finish resizing
332+ setTimeout ( ( ) => {
333+ viewer . resize ( ) ;
334+ viewer . scene . requestRender ( ) ;
335+ log . info ( "Cesium resized for" , newMode , "mode" ) ;
336+ } , 100 ) ;
337+ }
338+ }
339+
280340// Register handlers BEFORE connecting
281341app . onteardown = async ( ) => {
282342 log . info ( "App is being torn down" ) ;
@@ -289,6 +349,22 @@ app.onteardown = async () => {
289349
290350app . onerror = log . error ;
291351
352+ // Listen for host context changes (display mode, theme, etc.)
353+ app . onhostcontextchanged = ( params ) => {
354+ log . info ( "Host context changed:" , params ) ;
355+
356+ if ( params . displayMode ) {
357+ handleDisplayModeChange (
358+ params . displayMode as "inline" | "fullscreen" | "pip" ,
359+ ) ;
360+ }
361+
362+ // Update button if available modes changed
363+ if ( params . availableDisplayModes ) {
364+ updateFullscreenButton ( ) ;
365+ }
366+ } ;
367+
292368// Handle initial tool input (bounding box from show-map tool)
293369app . ontoolinput = ( params ) => {
294370 log . info ( "Received tool input:" , params ) ;
@@ -339,7 +415,6 @@ app.ontoolinput = (params) => {
339415 Cesium . Math . toDegrees ( viewer ! . camera . pitch ) ,
340416 ) ;
341417 } ) ;
342- setLabel ( args ?. label ) ;
343418 } , 500 ) ;
344419 }
345420 }
@@ -411,6 +486,29 @@ async function init() {
411486 // Connect to host (auto-creates PostMessageTransport)
412487 await app . connect ( ) ;
413488 log . info ( "Connected to host" ) ;
489+
490+ // Get initial display mode from host context
491+ const context = app . getHostContext ( ) ;
492+ if ( context ?. displayMode ) {
493+ currentDisplayMode = context . displayMode as
494+ | "inline"
495+ | "fullscreen"
496+ | "pip" ;
497+ }
498+ log . info ( "Initial display mode:" , currentDisplayMode ) ;
499+
500+ // Tell host our preferred size for inline mode
501+ if ( currentDisplayMode === "inline" ) {
502+ app . sendSizeChanged ( { height : PREFERRED_INLINE_HEIGHT } ) ;
503+ log . info ( "Sent initial size:" , PREFERRED_INLINE_HEIGHT ) ;
504+ }
505+
506+ // Set up fullscreen button
507+ updateFullscreenButton ( ) ;
508+ const fullscreenBtn = document . getElementById ( "fullscreen-btn" ) ;
509+ if ( fullscreenBtn ) {
510+ fullscreenBtn . addEventListener ( "click" , toggleFullscreen ) ;
511+ }
414512 } catch ( error ) {
415513 log . error ( "Failed to initialize:" , error ) ;
416514 const loadingEl = document . getElementById ( "loading" ) ;
0 commit comments