From 94cb8f99fb7faac9a48ea66ac37b9e87b5c92582 Mon Sep 17 00:00:00 2001 From: DerKoun Date: Mon, 24 Feb 2014 00:44:54 +0100 Subject: Full screen fixes (aspect ratio & IE11) & AR opt Full screen image now has correct aspect ratio (parent of canvas is full screen root, canvas size is adapted via styles). Full screen now works properly in Internet Explorer 11. It is now possible to optionally force a specific aspect ratio for the canvas (canvas size is adapted via styles, ratio for now has to be set manually in compiled JS). --- src/library_browser.js | 111 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 90 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/library_browser.js b/src/library_browser.js index 46082281..fce4d209 100644 --- a/src/library_browser.js +++ b/src/library_browser.js @@ -197,24 +197,33 @@ mergeInto(LibraryManager.library, { // Canvas event setup var canvas = Module['canvas']; + + // forced aspect ratio can be enabled by defining 'forcedAspectRatio' on Module + // Module['forcedAspectRatio'] = 4 / 3; + canvas.requestPointerLock = canvas['requestPointerLock'] || canvas['mozRequestPointerLock'] || - canvas['webkitRequestPointerLock']; + canvas['webkitRequestPointerLock'] || + canvas['msRequestPointerLock'] || + function(){}; canvas.exitPointerLock = document['exitPointerLock'] || document['mozExitPointerLock'] || document['webkitExitPointerLock'] || + document['msExitPointerLock'] || function(){}; // no-op if function does not exist canvas.exitPointerLock = canvas.exitPointerLock.bind(document); function pointerLockChange() { Browser.pointerLock = document['pointerLockElement'] === canvas || document['mozPointerLockElement'] === canvas || - document['webkitPointerLockElement'] === canvas; + document['webkitPointerLockElement'] === canvas || + document['msPointerLockElement'] === canvas; } document.addEventListener('pointerlockchange', pointerLockChange, false); document.addEventListener('mozpointerlockchange', pointerLockChange, false); document.addEventListener('webkitpointerlockchange', pointerLockChange, false); + document.addEventListener('mspointerlockchange', pointerLockChange, false); if (Module['elementPointerLock']) { canvas.addEventListener("click", function(ev) { @@ -340,22 +349,35 @@ mergeInto(LibraryManager.library, { if (typeof Browser.resizeCanvas === 'undefined') Browser.resizeCanvas = false; var canvas = Module['canvas']; + var canvasContainer = canvas.parentNode; function fullScreenChange() { Browser.isFullScreen = false; if ((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || document['mozFullScreenElement'] || document['mozFullscreenElement'] || - document['fullScreenElement'] || document['fullscreenElement']) === canvas) { + document['fullScreenElement'] || document['fullscreenElement'] || + document['msFullScreenElement'] || document['msFullscreenElement'] || + document['webkitCurrentFullScreenElement']) === canvasContainer) { canvas.cancelFullScreen = document['cancelFullScreen'] || document['mozCancelFullScreen'] || - document['webkitCancelFullScreen']; + document['webkitCancelFullScreen'] || + document['msExitFullscreen'] || + document['exitFullscreen'] || + function() {}; canvas.cancelFullScreen = canvas.cancelFullScreen.bind(document); if (Browser.lockPointer) canvas.requestPointerLock(); Browser.isFullScreen = true; if (Browser.resizeCanvas) Browser.setFullScreenCanvasSize(); - } else if (Browser.resizeCanvas){ - Browser.setWindowedCanvasSize(); + } else { + + // remove the full screen specific parent of the canvas again to restore the HTML structure from before going full screen + var canvasContainer = canvas.parentNode; + canvasContainer.parentNode.insertBefore(canvas, canvasContainer); + canvasContainer.parentNode.removeChild(canvasContainer); + + if (Browser.resizeCanvas) Browser.setWindowedCanvasSize(); } if (Module['onFullScreen']) Module['onFullScreen'](Browser.isFullScreen); + Browser.updateCanvasDimensions(canvas); } if (!Browser.fullScreenHandlersInstalled) { @@ -363,12 +385,20 @@ mergeInto(LibraryManager.library, { document.addEventListener('fullscreenchange', fullScreenChange, false); document.addEventListener('mozfullscreenchange', fullScreenChange, false); document.addEventListener('webkitfullscreenchange', fullScreenChange, false); + document.addEventListener('MSFullscreenChange', fullScreenChange, false); } - canvas.requestFullScreen = canvas['requestFullScreen'] || - canvas['mozRequestFullScreen'] || - (canvas['webkitRequestFullScreen'] ? function() { canvas['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); - canvas.requestFullScreen(); + // create a new parent to ensure the canvas has no siblings. this allows browsers to optimize full screen performance when its parent is the full screen root + var canvasContainer = document.createElement("div"); + canvas.parentNode.insertBefore(canvasContainer, canvas); + canvasContainer.appendChild(canvas); + + // use parent of canvas as full screen root to allow aspect ratio correction (Firefox stretches the root to screen size) + canvasContainer.requestFullScreen = canvasContainer['requestFullScreen'] || + canvasContainer['mozRequestFullScreen'] || + canvasContainer['msRequestFullscreen'] || + (canvasContainer['webkitRequestFullScreen'] ? function() { canvasContainer['webkitRequestFullScreen'](Element['ALLOW_KEYBOARD_INPUT']) } : null); + canvasContainer.requestFullScreen(); }, requestAnimationFrame: function requestAnimationFrame(func) { @@ -565,19 +595,13 @@ mergeInto(LibraryManager.library, { setCanvasSize: function(width, height, noUpdates) { var canvas = Module['canvas']; - canvas.width = width; - canvas.height = height; + Browser.updateCanvasDimensions(canvas, width, height); if (!noUpdates) Browser.updateResizeListeners(); }, windowedWidth: 0, windowedHeight: 0, setFullScreenCanvasSize: function() { - var canvas = Module['canvas']; - this.windowedWidth = canvas.width; - this.windowedHeight = canvas.height; - canvas.width = screen.width; - canvas.height = screen.height; // check if SDL is available if (typeof SDL != "undefined") { var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}}; @@ -588,9 +612,6 @@ mergeInto(LibraryManager.library, { }, setWindowedCanvasSize: function() { - var canvas = Module['canvas']; - canvas.width = this.windowedWidth; - canvas.height = this.windowedHeight; // check if SDL is available if (typeof SDL != "undefined") { var flags = {{{ makeGetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'i32', 0, 1) }}}; @@ -598,7 +619,55 @@ mergeInto(LibraryManager.library, { {{{ makeSetValue('SDL.screen+Runtime.QUANTUM_SIZE*0', '0', 'flags', 'i32') }}} } Browser.updateResizeListeners(); - } + }, + + updateCanvasDimensions : function(canvas, wNative, hNative) { + if (wNative && hNative) { + canvas.widthNative = wNative; + canvas.heightNative = hNative; + } else { + wNative = canvas.widthNative; + hNative = canvas.heightNative; + } + var w = wNative; + var h = hNative; + if (Module['forcedAspectRatio'] && Module['forcedAspectRatio'] > 0) { + if (w/h < Module['forcedAspectRatio']) { + w = Math.round(h * Module['forcedAspectRatio']); + } else { + h = Math.round(w / Module['forcedAspectRatio']); + } + } + if (((document['webkitFullScreenElement'] || document['webkitFullscreenElement'] || + document['mozFullScreenElement'] || document['mozFullscreenElement'] || + document['fullScreenElement'] || document['fullscreenElement'] || + document['msFullScreenElement'] || document['msFullscreenElement'] || + document['webkitCurrentFullScreenElement']) === canvas.parentNode) && (typeof screen != 'undefined')) { + var factor = Math.min(screen.width / w, screen.height / h); + w = Math.round(w * factor); + h = Math.round(h * factor); + } + if (Browser.resizeCanvas) { + if (canvas.width != w) canvas.width = w; + if (canvas.height != h) canvas.height = h; + if (typeof canvas.style != 'undefined') { + canvas.style.removeProperty( "width"); + canvas.style.removeProperty("height"); + } + } else { + if (canvas.width != wNative) canvas.width = wNative; + if (canvas.height != hNative) canvas.height = hNative; + if (typeof canvas.style != 'undefined') { + if (w != wNative || h != hNative) { + canvas.style.setProperty( "width", w + "px", "important"); + canvas.style.setProperty("height", h + "px", "important"); + } else { + canvas.style.removeProperty( "width"); + canvas.style.removeProperty("height"); + } + } + } + } }, -- cgit v1.2.3-18-g5258