NavigationHelpButton.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. import buildModuleUrl from "../../Core/buildModuleUrl.js";
  2. import defaultValue from "../../Core/defaultValue.js";
  3. import defined from "../../Core/defined.js";
  4. import destroyObject from "../../Core/destroyObject.js";
  5. import DeveloperError from "../../Core/DeveloperError.js";
  6. import FeatureDetection from "../../Core/FeatureDetection.js";
  7. import knockout from "../../ThirdParty/knockout.js";
  8. import getElement from "../getElement.js";
  9. import NavigationHelpButtonViewModel from "./NavigationHelpButtonViewModel.js";
  10. /**
  11. * <p>The NavigationHelpButton is a single button widget for displaying instructions for
  12. * navigating the globe with the mouse.</p><p style="clear: both;"></p><br/>
  13. *
  14. * @alias NavigationHelpButton
  15. * @constructor
  16. *
  17. * @param {Object} options Object with the following properties:
  18. * @param {Element|String} options.container The DOM element or ID that will contain the widget.
  19. * @param {Boolean} [options.instructionsInitiallyVisible=false] True if the navigation instructions should initially be visible; otherwise, false.
  20. *
  21. * @exception {DeveloperError} Element with id "container" does not exist in the document.
  22. *
  23. * @example
  24. * // In HTML head, include a link to the NavigationHelpButton.css stylesheet,
  25. * // and in the body, include: <div id="navigationHelpButtonContainer"></div>
  26. *
  27. * const navigationHelpButton = new Cesium.NavigationHelpButton({
  28. * container : 'navigationHelpButtonContainer'
  29. * });
  30. */
  31. function NavigationHelpButton(options) {
  32. //>>includeStart('debug', pragmas.debug);
  33. if (!defined(options) || !defined(options.container)) {
  34. throw new DeveloperError("options.container is required.");
  35. }
  36. //>>includeEnd('debug');
  37. const container = getElement(options.container);
  38. const viewModel = new NavigationHelpButtonViewModel();
  39. const showInsructionsDefault = defaultValue(
  40. options.instructionsInitiallyVisible,
  41. false
  42. );
  43. viewModel.showInstructions = showInsructionsDefault;
  44. viewModel._svgPath =
  45. "M16,1.466C7.973,1.466,1.466,7.973,1.466,16c0,8.027,6.507,14.534,14.534,14.534c8.027,0,14.534-6.507,14.534-14.534C30.534,7.973,24.027,1.466,16,1.466z M17.328,24.371h-2.707v-2.596h2.707V24.371zM17.328,19.003v0.858h-2.707v-1.057c0-3.19,3.63-3.696,3.63-5.963c0-1.034-0.924-1.826-2.134-1.826c-1.254,0-2.354,0.924-2.354,0.924l-1.541-1.915c0,0,1.519-1.584,4.137-1.584c2.487,0,4.796,1.54,4.796,4.136C21.156,16.208,17.328,16.627,17.328,19.003z";
  46. const wrapper = document.createElement("span");
  47. wrapper.className = "cesium-navigationHelpButton-wrapper";
  48. container.appendChild(wrapper);
  49. const button = document.createElement("button");
  50. button.type = "button";
  51. button.className =
  52. "cesium-button cesium-toolbar-button cesium-navigation-help-button";
  53. button.setAttribute(
  54. "data-bind",
  55. "\
  56. attr: { title: tooltip },\
  57. click: command,\
  58. cesiumSvgPath: { path: _svgPath, width: 32, height: 32 }"
  59. );
  60. wrapper.appendChild(button);
  61. const instructionContainer = document.createElement("div");
  62. instructionContainer.className = "cesium-navigation-help";
  63. instructionContainer.setAttribute(
  64. "data-bind",
  65. 'css: { "cesium-navigation-help-visible" : showInstructions}'
  66. );
  67. wrapper.appendChild(instructionContainer);
  68. const mouseButton = document.createElement("button");
  69. mouseButton.type = "button";
  70. mouseButton.className =
  71. "cesium-navigation-button cesium-navigation-button-left";
  72. mouseButton.setAttribute(
  73. "data-bind",
  74. 'click: showClick, css: {"cesium-navigation-button-selected": !_touch, "cesium-navigation-button-unselected": _touch}'
  75. );
  76. const mouseIcon = document.createElement("img");
  77. mouseIcon.src = buildModuleUrl("Widgets/Images/NavigationHelp/Mouse.svg");
  78. mouseIcon.className = "cesium-navigation-button-icon";
  79. mouseIcon.style.width = "25px";
  80. mouseIcon.style.height = "25px";
  81. mouseButton.appendChild(mouseIcon);
  82. mouseButton.appendChild(document.createTextNode("Mouse"));
  83. const touchButton = document.createElement("button");
  84. touchButton.type = "button";
  85. touchButton.className =
  86. "cesium-navigation-button cesium-navigation-button-right";
  87. touchButton.setAttribute(
  88. "data-bind",
  89. 'click: showTouch, css: {"cesium-navigation-button-selected": _touch, "cesium-navigation-button-unselected": !_touch}'
  90. );
  91. const touchIcon = document.createElement("img");
  92. touchIcon.src = buildModuleUrl("Widgets/Images/NavigationHelp/Touch.svg");
  93. touchIcon.className = "cesium-navigation-button-icon";
  94. touchIcon.style.width = "25px";
  95. touchIcon.style.height = "25px";
  96. touchButton.appendChild(touchIcon);
  97. touchButton.appendChild(document.createTextNode("Touch"));
  98. instructionContainer.appendChild(mouseButton);
  99. instructionContainer.appendChild(touchButton);
  100. const clickInstructions = document.createElement("div");
  101. clickInstructions.className =
  102. "cesium-click-navigation-help cesium-navigation-help-instructions";
  103. clickInstructions.setAttribute(
  104. "data-bind",
  105. 'css: { "cesium-click-navigation-help-visible" : !_touch}'
  106. );
  107. clickInstructions.innerHTML = `\
  108. <table>\
  109. <tr>\
  110. <td><img src="${buildModuleUrl(
  111. "Widgets/Images/NavigationHelp/MouseLeft.svg"
  112. )}" width="48" height="48" /></td>\
  113. <td>\
  114. <div class="cesium-navigation-help-pan">Pan view</div>\
  115. <div class="cesium-navigation-help-details">Left click + drag</div>\
  116. </td>\
  117. </tr>\
  118. <tr>\
  119. <td><img src="${buildModuleUrl(
  120. "Widgets/Images/NavigationHelp/MouseRight.svg"
  121. )}" width="48" height="48" /></td>\
  122. <td>\
  123. <div class="cesium-navigation-help-zoom">Zoom view</div>\
  124. <div class="cesium-navigation-help-details">Right click + drag, or</div>\
  125. <div class="cesium-navigation-help-details">Mouse wheel scroll</div>\
  126. </td>\
  127. </tr>\
  128. <tr>\
  129. <td><img src="${buildModuleUrl(
  130. "Widgets/Images/NavigationHelp/MouseMiddle.svg"
  131. )}" width="48" height="48" /></td>\
  132. <td>\
  133. <div class="cesium-navigation-help-rotate">Rotate view</div>\
  134. <div class="cesium-navigation-help-details">Middle click + drag, or</div>\
  135. <div class="cesium-navigation-help-details">CTRL + Left/Right click + drag</div>\
  136. </td>\
  137. </tr>\
  138. </table>`;
  139. instructionContainer.appendChild(clickInstructions);
  140. const touchInstructions = document.createElement("div");
  141. touchInstructions.className =
  142. "cesium-touch-navigation-help cesium-navigation-help-instructions";
  143. touchInstructions.setAttribute(
  144. "data-bind",
  145. 'css: { "cesium-touch-navigation-help-visible" : _touch}'
  146. );
  147. touchInstructions.innerHTML = `\
  148. <table>\
  149. <tr>\
  150. <td><img src="${buildModuleUrl(
  151. "Widgets/Images/NavigationHelp/TouchDrag.svg"
  152. )}" width="70" height="48" /></td>\
  153. <td>\
  154. <div class="cesium-navigation-help-pan">Pan view</div>\
  155. <div class="cesium-navigation-help-details">One finger drag</div>\
  156. </td>\
  157. </tr>\
  158. <tr>\
  159. <td><img src="${buildModuleUrl(
  160. "Widgets/Images/NavigationHelp/TouchZoom.svg"
  161. )}" width="70" height="48" /></td>\
  162. <td>\
  163. <div class="cesium-navigation-help-zoom">Zoom view</div>\
  164. <div class="cesium-navigation-help-details">Two finger pinch</div>\
  165. </td>\
  166. </tr>\
  167. <tr>\
  168. <td><img src="${buildModuleUrl(
  169. "Widgets/Images/NavigationHelp/TouchTilt.svg"
  170. )}" width="70" height="48" /></td>\
  171. <td>\
  172. <div class="cesium-navigation-help-rotate">Tilt view</div>\
  173. <div class="cesium-navigation-help-details">Two finger drag, same direction</div>\
  174. </td>\
  175. </tr>\
  176. <tr>\
  177. <td><img src="${buildModuleUrl(
  178. "Widgets/Images/NavigationHelp/TouchRotate.svg"
  179. )}" width="70" height="48" /></td>\
  180. <td>\
  181. <div class="cesium-navigation-help-tilt">Rotate view</div>\
  182. <div class="cesium-navigation-help-details">Two finger drag, opposite direction</div>\
  183. </td>\
  184. </tr>\
  185. </table>`;
  186. instructionContainer.appendChild(touchInstructions);
  187. knockout.applyBindings(viewModel, wrapper);
  188. this._container = container;
  189. this._viewModel = viewModel;
  190. this._wrapper = wrapper;
  191. this._closeInstructions = function (e) {
  192. if (!wrapper.contains(e.target)) {
  193. viewModel.showInstructions = false;
  194. }
  195. };
  196. if (FeatureDetection.supportsPointerEvents()) {
  197. document.addEventListener("pointerdown", this._closeInstructions, true);
  198. } else {
  199. document.addEventListener("mousedown", this._closeInstructions, true);
  200. document.addEventListener("touchstart", this._closeInstructions, true);
  201. }
  202. }
  203. Object.defineProperties(NavigationHelpButton.prototype, {
  204. /**
  205. * Gets the parent container.
  206. * @memberof NavigationHelpButton.prototype
  207. *
  208. * @type {Element}
  209. */
  210. container: {
  211. get: function () {
  212. return this._container;
  213. },
  214. },
  215. /**
  216. * Gets the view model.
  217. * @memberof NavigationHelpButton.prototype
  218. *
  219. * @type {NavigationHelpButtonViewModel}
  220. */
  221. viewModel: {
  222. get: function () {
  223. return this._viewModel;
  224. },
  225. },
  226. });
  227. /**
  228. * @returns {Boolean} true if the object has been destroyed, false otherwise.
  229. */
  230. NavigationHelpButton.prototype.isDestroyed = function () {
  231. return false;
  232. };
  233. /**
  234. * Destroys the widget. Should be called if permanently
  235. * removing the widget from layout.
  236. */
  237. NavigationHelpButton.prototype.destroy = function () {
  238. if (FeatureDetection.supportsPointerEvents()) {
  239. document.removeEventListener("pointerdown", this._closeInstructions, true);
  240. } else {
  241. document.removeEventListener("mousedown", this._closeInstructions, true);
  242. document.removeEventListener("touchstart", this._closeInstructions, true);
  243. }
  244. knockout.cleanNode(this._wrapper);
  245. this._container.removeChild(this._wrapper);
  246. return destroyObject(this);
  247. };
  248. export default NavigationHelpButton;