Source: Widgets/VRButton/VRButtonViewModel.js

  1. /*global define*/
  2. define([
  3. '../../Core/defaultValue',
  4. '../../Core/defined',
  5. '../../Core/defineProperties',
  6. '../../Core/destroyObject',
  7. '../../Core/DeveloperError',
  8. '../../Core/Fullscreen',
  9. '../../ThirdParty/knockout',
  10. '../../ThirdParty/NoSleep',
  11. '../createCommand',
  12. '../getElement'
  13. ], function(
  14. defaultValue,
  15. defined,
  16. defineProperties,
  17. destroyObject,
  18. DeveloperError,
  19. Fullscreen,
  20. knockout,
  21. NoSleep,
  22. createCommand,
  23. getElement) {
  24. 'use strict';
  25. function lockScreen(orientation) {
  26. var locked = false;
  27. var screen = window.screen;
  28. if (defined(screen)) {
  29. if (defined(screen.lockOrientation)) {
  30. locked = screen.lockOrientation(orientation);
  31. } else if (defined(screen.mozLockOrientation)) {
  32. locked = screen.mozLockOrientation(orientation);
  33. } else if (defined(screen.msLockOrientation)) {
  34. locked = screen.msLockOrientation(orientation);
  35. } else if (defined(screen.orientation && screen.orientation.lock)) {
  36. locked = screen.orientation.lock(orientation);
  37. }
  38. }
  39. return locked;
  40. }
  41. function unlockScreen() {
  42. var screen = window.screen;
  43. if (defined(screen)) {
  44. if (defined(screen.unlockOrientation)) {
  45. screen.unlockOrientation();
  46. } else if (defined(screen.mozUnlockOrientation)) {
  47. screen.mozUnlockOrientation();
  48. } else if (defined(screen.msUnlockOrientation)) {
  49. screen.msUnlockOrientation();
  50. } else if (defined(screen.orientation && screen.orientation.unlock)) {
  51. screen.orientation.unlock();
  52. }
  53. }
  54. }
  55. function toggleVR(viewModel, scene, isVRMode) {
  56. if (isVRMode()) {
  57. scene.useWebVR = false;
  58. if (viewModel._locked) {
  59. unlockScreen();
  60. viewModel._locked = false;
  61. }
  62. viewModel._noSleep.disable();
  63. Fullscreen.exitFullscreen();
  64. isVRMode(false);
  65. } else {
  66. if (!Fullscreen.fullscreen) {
  67. Fullscreen.requestFullscreen(viewModel._vrElement);
  68. }
  69. viewModel._noSleep.enable();
  70. if (!viewModel._locked) {
  71. viewModel._locked = lockScreen('landscape');
  72. }
  73. scene.useWebVR = true;
  74. isVRMode(true);
  75. }
  76. }
  77. /**
  78. * The view model for {@link VRButton}.
  79. * @alias VRButtonViewModel
  80. * @constructor
  81. *
  82. * @param {Scene} scene The scene.
  83. * @param {Element|String} [vrElement=document.body] The element or id to be placed into VR mode.
  84. */
  85. function VRButtonViewModel(scene, vrElement) {
  86. //>>includeStart('debug', pragmas.debug);
  87. if (!defined(scene)) {
  88. throw new DeveloperError('scene is required.');
  89. }
  90. //>>includeEnd('debug');
  91. var that = this;
  92. var isEnabled = knockout.observable(Fullscreen.enabled);
  93. var isVRMode = knockout.observable(false);
  94. /**
  95. * Gets whether or not VR mode is active.
  96. *
  97. * @type {Boolean}
  98. */
  99. this.isVRMode = undefined;
  100. knockout.defineProperty(this, 'isVRMode', {
  101. get : function() {
  102. return isVRMode();
  103. }
  104. });
  105. /**
  106. * Gets or sets whether or not VR functionality should be enabled.
  107. *
  108. * @type {Boolean}
  109. * @see Fullscreen.enabled
  110. */
  111. this.isVREnabled = undefined;
  112. knockout.defineProperty(this, 'isVREnabled', {
  113. get : function() {
  114. return isEnabled();
  115. },
  116. set : function(value) {
  117. isEnabled(value && Fullscreen.enabled);
  118. }
  119. });
  120. /**
  121. * Gets the tooltip. This property is observable.
  122. *
  123. * @type {String}
  124. */
  125. this.tooltip = undefined;
  126. knockout.defineProperty(this, 'tooltip', function() {
  127. if (!isEnabled()) {
  128. return 'VR mode is unavailable';
  129. }
  130. return isVRMode() ? 'Exit VR mode' : 'Enter VR mode';
  131. });
  132. this._locked = false;
  133. this._noSleep = new NoSleep();
  134. this._command = createCommand(function() {
  135. toggleVR(that, scene, isVRMode);
  136. }, knockout.getObservable(this, 'isVREnabled'));
  137. this._vrElement = defaultValue(getElement(vrElement), document.body);
  138. this._callback = function() {
  139. if (!Fullscreen.fullscreen && isVRMode()) {
  140. scene.useWebVR = false;
  141. if (that._locked) {
  142. unlockScreen();
  143. that._locked = false;
  144. }
  145. that._noSleep.disable();
  146. isVRMode(false);
  147. }
  148. };
  149. document.addEventListener(Fullscreen.changeEventName, this._callback);
  150. }
  151. defineProperties(VRButtonViewModel.prototype, {
  152. /**
  153. * Gets or sets the HTML element to place into VR mode when the
  154. * corresponding button is pressed.
  155. * @memberof VRButtonViewModel.prototype
  156. *
  157. * @type {Element}
  158. */
  159. vrElement : {
  160. //TODO:@exception {DeveloperError} value must be a valid HTML Element.
  161. get : function() {
  162. return this._vrElement;
  163. },
  164. set : function(value) {
  165. //>>includeStart('debug', pragmas.debug);
  166. if (!(value instanceof Element)) {
  167. throw new DeveloperError('value must be a valid Element.');
  168. }
  169. //>>includeEnd('debug');
  170. this._vrElement = value;
  171. }
  172. },
  173. /**
  174. * Gets the Command to toggle VR mode.
  175. * @memberof VRButtonViewModel.prototype
  176. *
  177. * @type {Command}
  178. */
  179. command : {
  180. get : function() {
  181. return this._command;
  182. }
  183. }
  184. });
  185. /**
  186. * @returns {Boolean} true if the object has been destroyed, false otherwise.
  187. */
  188. VRButtonViewModel.prototype.isDestroyed = function() {
  189. return false;
  190. };
  191. /**
  192. * Destroys the view model. Should be called to
  193. * properly clean up the view model when it is no longer needed.
  194. */
  195. VRButtonViewModel.prototype.destroy = function() {
  196. destroyObject(this);
  197. };
  198. return VRButtonViewModel;
  199. });