@@ -10,7 +10,7 @@ window.GDQUEST = ((/** @type {GDQuestLib} */ GDQUEST) => {
10
10
document . getElementById ( "canvas-frame" )
11
11
) ;
12
12
13
- const noOp = ( ) => { } ;
13
+ const noOp = ( ) => { } ;
14
14
15
15
const throttle = ( callback , limit = 50 ) => {
16
16
let waiting = false ;
@@ -26,14 +26,14 @@ window.GDQUEST = ((/** @type {GDQuestLib} */ GDQUEST) => {
26
26
27
27
const aspectRatio =
28
28
( maxW = 0 , maxH = 0 ) =>
29
- ( currentWidth = window . innerWidth , currentHeight = window . innerHeight ) => {
30
- const ratioW = currentWidth / maxW ;
31
- const ratioH = currentHeight / maxH ;
32
- const ratio = Math . min ( ratioW , ratioH ) ;
33
- const width = maxW * ratio ;
34
- const height = maxH * ratio ;
35
- return { width, height, ratio } ;
36
- } ;
29
+ ( currentWidth = window . innerWidth , currentHeight = window . innerHeight ) => {
30
+ const ratioW = currentWidth / maxW ;
31
+ const ratioH = currentHeight / maxH ;
32
+ const ratio = Math . min ( ratioW , ratioH ) ;
33
+ const width = maxW * ratio ;
34
+ const height = maxH * ratio ;
35
+ return { width, height, ratio } ;
36
+ } ;
37
37
38
38
/**
39
39
* Returns a proxied console that can be turned off and on by appending
@@ -124,7 +124,6 @@ window.GDQUEST = ((/** @type {GDQuestLib} */ GDQUEST) => {
124
124
GDQUEST . events = {
125
125
onError : makeSignal ( ) ,
126
126
onGodotLoaded : makeSignal ( ) ,
127
- onFullScreen : makeSignal ( ) ,
128
127
onResize : makeSignal ( ) ,
129
128
} ;
130
129
@@ -356,45 +355,45 @@ window.GDQUEST = ((/** @type {GDQuestLib} */ GDQUEST) => {
356
355
357
356
const makeLogFunction =
358
357
( level = LEVELS . INFO ) =>
359
- /** @type {LogFunction } */
360
- ( anything , msg = "" ) => {
361
- if ( typeof anything === "string" || typeof anything === "number" ) {
362
- msg = String ( anything ) ;
363
- anything = null ;
364
- }
365
-
366
- const time = Date . now ( ) ;
367
- /** @type {LogLine } */
368
- const log_line = { time, level, msg, ...( anything || { } ) } ;
369
- log_lines . push ( log_line ) ;
370
- localStorage . setItem ( KEY , JSON . stringify ( log_lines ) ) ;
371
-
372
- if ( level < 30 ) {
373
- if ( anything ) {
374
- debug . log ( msg , anything ) ;
375
- } else {
376
- debug . log ( msg ) ;
377
- }
378
- } else if ( level < 40 ) {
379
- if ( anything ) {
380
- debug . info ( msg , anything ) ;
381
- } else {
382
- debug . info ( msg ) ;
383
- }
384
- } else if ( level < 50 ) {
385
- if ( anything ) {
386
- debug . warn ( msg , anything ) ;
387
- } else {
388
- debug . warn ( msg ) ;
358
+ /** @type {LogFunction } */
359
+ ( anything , msg = "" ) => {
360
+ if ( typeof anything === "string" || typeof anything === "number" ) {
361
+ msg = String ( anything ) ;
362
+ anything = null ;
389
363
}
390
- } else {
391
- if ( anything ) {
392
- debug . error ( msg , anything ) ;
364
+
365
+ const time = Date . now ( ) ;
366
+ /** @type {LogLine } */
367
+ const log_line = { time, level, msg, ...( anything || { } ) } ;
368
+ log_lines . push ( log_line ) ;
369
+ localStorage . setItem ( KEY , JSON . stringify ( log_lines ) ) ;
370
+
371
+ if ( level < 30 ) {
372
+ if ( anything ) {
373
+ debug . log ( msg , anything ) ;
374
+ } else {
375
+ debug . log ( msg ) ;
376
+ }
377
+ } else if ( level < 40 ) {
378
+ if ( anything ) {
379
+ debug . info ( msg , anything ) ;
380
+ } else {
381
+ debug . info ( msg ) ;
382
+ }
383
+ } else if ( level < 50 ) {
384
+ if ( anything ) {
385
+ debug . warn ( msg , anything ) ;
386
+ } else {
387
+ debug . warn ( msg ) ;
388
+ }
393
389
} else {
394
- debug . error ( msg ) ;
390
+ if ( anything ) {
391
+ debug . error ( msg , anything ) ;
392
+ } else {
393
+ debug . error ( msg ) ;
394
+ }
395
395
}
396
- }
397
- } ;
396
+ } ;
398
397
399
398
/** @type { Log['display'] } */
400
399
const display = ( ) => console . table ( get ( ) ) ;
@@ -466,163 +465,47 @@ window.GDQUEST = ((/** @type {GDQuestLib} */ GDQUEST) => {
466
465
}
467
466
468
467
fullscreen: {
469
- const debug = makeLogger ( "fullscreen" ) ;
470
- /**
471
- * Browsers make it exceedingly hard to get that information reliably, so
472
- * we have to rely on a bunch of different strategies
468
+ /*
469
+ * Create a button with a label.
473
470
*/
474
- const isIt = ( ( ) => {
475
- /**
476
- * This is an invisible element which changes position when the browser
477
- * is full screen. We do this through the media query:
478
- * ```css
479
- * @media all and (display-mode: fullscreen) {
480
- * #fullscreen-detector {
481
- * top: 1px;
482
- * }
483
- * }
484
- * ```
485
- */
486
- const fullScreenPoller = ( ( ) => {
487
- const el = document . createElement ( "div" ) ;
488
- el . id = "fullscreen-detector" ;
489
- document . body . appendChild ( el ) ;
490
- return el ;
491
- } ) ( ) ;
492
-
493
- /** check is the element has moved */
494
- const checkCSSMediaQuery = ( ) => {
495
- const top = fullScreenPoller . getBoundingClientRect ( ) . top > 0 ;
496
- return top ;
497
- } ;
498
-
499
- /** check if browser has borders. Take zoom into account */
500
- const checkWindowMargins = ( ) => {
501
- const zoom = window . outerWidth / window . innerWidth ;
502
- const hasMargin =
503
- Math . abs ( window . innerWidth * zoom - screen . width ) < 10 ;
504
- return hasMargin ;
505
- } ;
506
-
507
- /** check if some element has been set fullscreen through the JS API */
508
- const checkFullScreenElement = ( ) => {
509
- const hasSomeFullScreenElement = document . fullscreenElement !== null ;
510
- return hasSomeFullScreenElement ;
511
- } ;
512
-
513
- return {
514
- checkFullScreenElement,
515
- checkCSSMediaQuery,
516
- checkWindowMargins,
517
- } ;
518
- } ) ( ) ;
519
-
520
- let isFullScreen = false ;
521
- let wasFullScreen = false ;
522
-
523
- /** use the JS API to call fullscreen */
524
- const toggle = ( ) => {
525
- //debug.info(`will`, isFullScreen ? "exit" : "enter", "fullscreen mode");
526
- const isItActuallyFullScreen = isIt . checkCSSMediaQuery ( ) ;
527
- if ( isItActuallyFullScreen !== isFullScreen ) {
528
- debug . error (
529
- `Mismatch! Expected fullscreen to be ${ isFullScreen } , but it is ${ isItActuallyFullScreen } .`
530
- ) ;
531
- if ( isItActuallyFullScreen ) {
532
- debug . error (
533
- `Cannot exit a fullscreen mode set natively. Bailing out!`
534
- ) ;
535
- return ;
536
- } else {
537
- debug . warn ( `Will set our fullscreen now` ) ;
538
- isFullScreen = false ;
539
- }
540
- }
541
- isFullScreen
542
- ? document . exitFullscreen ( )
543
- : document . documentElement . requestFullscreen ( ) ;
544
- isFullScreen = ! isFullScreen ;
545
- } ;
546
-
547
- /**
548
- * Create a button with the proper classes; change class when
549
- * fullscreen event happens
550
- */
551
- const button = ( ( ) => {
552
- const normalClassName = "button-fullscreen" ;
553
-
471
+ const makeFullscreenButton = ( className , onClick = ( ) => { } ) => {
554
472
const button = document . createElement ( "button" ) ;
555
- button . classList . add ( normalClassName ) ;
556
- button . addEventListener ( "click" , toggle ) ;
473
+ button . classList . add ( className ) ;
474
+ button . addEventListener ( "click" , onClick ) ;
557
475
558
476
const label = document . createElement ( "span" ) ;
559
477
label . textContent = "toggle Fullscreen" ;
560
478
button . appendChild ( label ) ;
561
479
return button ;
562
- } ) ( ) ;
480
+ }
563
481
564
482
/**
565
- * Only add the button if Godot has loaded
483
+ * Create a button with the proper classes; change class when
484
+ * fullscreen event happens
566
485
*/
567
- GDQUEST . events . onGodotLoaded . once ( ( ) => {
568
- canvasContainer . appendChild ( button ) ;
486
+ const fullscreenOnButton = makeFullscreenButton ( "button-fullscreen-on" , ( ) => document . documentElement . requestFullscreen ( ) ) ;
487
+ const fullscreenOffButton = makeFullscreenButton ( "button-fullscreen-off" , ( ) => {
488
+ document . exitFullscreen ( ) . catch ( ( err ) => err . name !== "TypeError" && console . error ( err ) ) ;
569
489
} ) ;
570
490
571
491
/**
572
- * Checks if the actual fullscreen state was set through an API
573
- * If we're _exiting_ fullscreen, then we can't check, but we
574
- * set `isFullScreen` to `false`.
575
- * @param {boolean } isItActuallyFullScreen
576
- */
577
- const wasItOurFullScreen = ( isItActuallyFullScreen ) => {
578
- if ( isItActuallyFullScreen ) {
579
- if ( isIt . checkFullScreenElement ( ) ) {
580
- debug . log ( "full screen changed through our button" ) ;
581
- } else {
582
- // that means fullscreen was set _not_ through our button
583
- debug . warn ( "full screen changed through shortcut, hiding the button" ) ;
584
- document . body . classList . add ( "native-fullscreen" ) ;
585
- }
586
- } else {
587
- debug . log ( "exiting fullscreen" ) ;
588
- isFullScreen = false ;
589
- document . body . classList . remove ( "native-fullscreen" ) ;
590
- }
591
- } ;
592
-
593
- /**
594
- * @param {Event } evt
492
+ * Only add the button if Godot has loaded
595
493
*/
596
- const onFullScreenChange = ( evt ) => {
597
- const isItActuallyFullScreen = isIt . checkFullScreenElement ( ) ;
598
- if ( isItActuallyFullScreen != wasFullScreen ) {
599
- wasFullScreen = isItActuallyFullScreen ;
600
- debug . info ( `[ ${ evt . type } ]` , `full screen state changed` ) ;
601
- const wasIt = wasItOurFullScreen ( isItActuallyFullScreen ) ;
602
- GDQUEST . events . onFullScreen . emit ( isItActuallyFullScreen , wasIt ) ;
603
- }
604
- } ;
494
+ GDQUEST . events . onGodotLoaded . once ( ( ) => {
495
+ canvasContainer . appendChild ( fullscreenOnButton ) ;
496
+ canvasContainer . appendChild ( fullscreenOffButton ) ;
497
+ } ) ;
605
498
606
499
document . addEventListener ( "keydown" , ( event ) => {
607
- if ( event . code == ` F11` ) {
500
+ if ( event . code === " F11" ) {
608
501
event . preventDefault ( ) ;
609
- button . focus ( ) ;
610
- debug . log ( "Stopped F11" ) ;
502
+ if ( getComputedStyle ( fullscreenOnButton ) . display !== "none" ) {
503
+ fullscreenOnButton . click ( ) ;
504
+ } else if ( getComputedStyle ( fullscreenOffButton ) . display !== "none" ) {
505
+ fullscreenOffButton . click ( ) ;
506
+ }
611
507
}
612
508
} ) ;
613
-
614
- /**
615
- * This is for when using the JS API
616
- */
617
- document . addEventListener ( "fullscreenchange" , onFullScreenChange ) ;
618
- /**
619
- * This is for buttons, shortcuts, and other methods for setting fullscreen.
620
- * We could also potentially poll for size after keypresses, but this seems
621
- * to work well enough
622
- */
623
- GDQUEST . events . onResize . connect ( onFullScreenChange ) ;
624
-
625
- GDQUEST . fullScreen = { isIt, toggle } ;
626
509
}
627
510
628
511
return GDQUEST ;
0 commit comments