/home/lindsay/xeolabs/xeogl-next/xeogl/examples/js/annotations/button.js
API Docs for:

File: /home/lindsay/xeolabs/xeogl-next/xeogl/examples/js/annotations/button.js

  1. /**
  2. A **Button** is a clickable {{#crossLink "Pin"}}{{/crossLink}} that's attached to the surface of an {{#crossLink "Mesh"}}{{/crossLink}}.
  3.  
  4. @class Button
  5. @module xeogl
  6. @submodule annotations
  7. @constructor
  8. @param [scene] {Scene} Parent {{#crossLink "Scene"}}Scene{{/crossLink}} - creates this Pin in the default
  9. {{#crossLink "Scene"}}Scene{{/crossLink}} when omitted.
  10. @param [cfg] {*} Configs
  11. @param [cfg.id] {String} Optional ID, unique among all components in the parent {{#crossLink "Scene"}}Scene{{/crossLink}},
  12. generated automatically when omitted.
  13. @param [cfg.meta] {String:Object} Optional map of user-defined metadata to attach to the Button.
  14. @param [cfg.mesh] {Number|String|Mesh} ID or instance of the {{#crossLink "Mesh"}}{{/crossLink}} the Button is attached to.
  15. @param [cfg.bary=[0.3,0.3,0.3]] {Float32Array} Barycentric coordinates of the Button within its triangle.
  16. @param [cfg.primIndex=0] {Number} Index of the triangle containing the Button. Within the {{#crossLink "Mesh"}}{{/crossLink}} {{#crossLink "Geometry"}}{{/crossLink}}
  17. {{#crossLink "Geometry/indices:property"}}{{/crossLink}}, this is the index of the first
  18. element for that triangle.
  19. @param [cfg.offset=0.2] {Number} How far the Button is lifted out of its triangle, along the surface normal vector. This is used when occlusion culling, to ensure that the Button is not lost inside the surface it's attached to.
  20. @param [cfg.occludable=true] {Boolean} Indicates whether occlusion testing is performed for the Button, where it will be flagged invisible whenever it's hidden by something else in the 3D camera.
  21. @param [cfg.glyph=""] {String} Short piece of text to show inside the pin for the Button. Automatically truncated to 2 characters.
  22. @param [cfg.pinShown=true] {Boolean} Specifies whether a UI element is shown at the Button's pin position (typically a circle).
  23. @param [cfg.zIndex] {Number} Optional CSS z-index value for HTML button element.
  24. @extends Pin
  25. */
  26. xeogl.Button = xeogl.Pin.extend({
  27.  
  28. type: "xeogl.Button",
  29.  
  30. _init: function (cfg) {
  31.  
  32. this._super(cfg);
  33.  
  34. this._spotClickable = document.createElement("a");
  35. this._spotClickable.href = "javascript:xeogl.scenes[\"" + this.scene.id + "\"].components[\"" + this.id + "\"]._pinClicked()";
  36. this._spotClickable.style["display"] = "block";
  37. this._spotClickable.style["content"] = '';
  38. this._spotClickable.style["position"] = "absolute";
  39. this._spotClickable.style["width"] = "50px";
  40. this._spotClickable.style["height"] = "50px";
  41. this._spotClickable.style["border-radius"] = "25px;";
  42. this._spotClickable.style["visibility"] = "hidden";
  43. this._spotClickable.style["z-index"] = 0;
  44. document.body.appendChild(this._spotClickable);
  45.  
  46. this._spot = document.createElement("div");
  47. this._spot.style["pointer-events"] = "none";
  48. this._spot.innerText = "i";
  49. this._spot.style["color"] = "#ffffff";
  50. this._spot.style["line-height"] = 1.8;
  51. this._spot.style["text-align"] = "center";
  52. this._spot.style["font-family"] = "monospace";
  53. this._spot.style["font-weight"] = "bold";
  54. this._spot.style["position"] = "absolute";
  55. this._spot.style["width"] = "25px";
  56. this._spot.style["height"] = "25px";
  57. this._spot.style["border-radius"] = "15px";
  58. this._spot.style["border"] = "2px solid #ffffff";
  59. this._spot.style["background"] = "black";
  60. this._spot.style["visibility"] = "hidden";
  61. this._spot.style["box-shadow"] = "5px 5px 15px 1px #000000";
  62. this._spot.style["z-index"] = 0;
  63.  
  64. const zIndex = cfg.zIndex || 0;
  65. this._spot.style["z-index"] = zIndex;
  66. this._spot.style["zIndex"] = zIndex;
  67. this._spotClickable.style["z-index"] = zIndex;
  68. this._spotClickable.style["zIndex"] = zIndex;
  69.  
  70. document.body.appendChild(this._spot);
  71.  
  72. this.glyph = cfg.glyph;
  73. this.pinShown = cfg.pinShown;
  74.  
  75. this._tick = this.scene.on("tick", this._updateLayout, this);
  76.  
  77. this.on("visible", this._updateVisibility, this);
  78.  
  79. // this._updateVisibility();
  80. },
  81.  
  82. _pinClicked: function () {
  83.  
  84. /**
  85. Fired whenever the mouse is clicked on this Button's {{#crossLink "Button/pin:property"}}{{/crossLink}}.
  86.  
  87. @event pinClicked
  88. */
  89. this.fire("pinClicked", this)
  90. },
  91.  
  92. _props: {
  93.  
  94. /**
  95. Short piece of text to show inside the pin for the Button.
  96.  
  97. Usually this would be a single number or letter.
  98.  
  99. Automatically truncated to 2 characters.
  100.  
  101. Fires a {{#crossLink "Button/glyph:event"}}{{/crossLink}} event on change.
  102.  
  103. @property glyph
  104. @default ""
  105. @type {String}
  106. */
  107. glyph: {
  108. set: function (glyph) {
  109.  
  110. if (this._glyph === glyph) {
  111. return;
  112. }
  113.  
  114. this._glyph = glyph || ""; // TODO: Limit to 2 chars
  115. this._spot.innerText = this._glyph;
  116.  
  117. /**
  118. Fired whenever this Button's {{#crossLink "Button/glyph:property"}}{{/crossLink}} property changes.
  119.  
  120. @event glyph
  121. @param value {Number} The property's new value
  122. */
  123. this.fire("glyph", this._glyph);
  124. },
  125. get: function () {
  126. return this._glyph;
  127. }
  128. },
  129.  
  130. /**
  131. Specifies whether a UI element is shown at the Button's pin position (typically a circle).
  132.  
  133. Fires a {{#crossLink "Button/pinShown:event"}}{{/crossLink}} event on change.
  134.  
  135. @property pinShown
  136. @default true
  137. @type {Boolean}
  138. */
  139. pinShown: {
  140. set: function (shown) {
  141.  
  142. shown = shown !== false;
  143.  
  144. if (this._pinShown === shown) {
  145. return;
  146. }
  147.  
  148. this._pinShown = shown;
  149. this._spot.style.visibility = this._pinShown ? "visible" : "hidden";
  150. this._spotClickable.style.visibility = this._pinShown ? "visible" : "hidden";
  151.  
  152. /**
  153. Fired whenever this Button's {{#crossLink "Button/pinShown:property"}}{{/crossLink}} property changes.
  154.  
  155. @event pinShown
  156. @param value {Number} The property's new value
  157. */
  158. this.fire("pinShown", this._pinShown);
  159. },
  160. get: function () {
  161. return this._pinShown;
  162. }
  163. }
  164. },
  165.  
  166. _updateVisibility: function () {
  167. const visible = this.visible;
  168. this._spotClickable.style.visibility = visible && this._pinShown ? "visible" : "hidden";
  169. this._spot.style.visibility = visible && this._pinShown ? "visible" : "hidden";
  170. },
  171.  
  172. _updateLayout: function () {
  173. const visible = this.visible;
  174. if (visible) {
  175. const canvas = this.scene.canvas.canvas;
  176. const left = canvas.offsetLeft;
  177. const top = canvas.offsetTop;
  178. const canvasPos = this.canvasPos;
  179. this._spot.style.left = (Math.floor(left + canvasPos[0]) - 12) + "px";
  180. this._spot.style.top = (Math.floor(top + canvasPos[1]) - 12) + "px";
  181. this._spotClickable.style.left = (Math.floor(left + canvasPos[0]) - 25 + 1) + "px";
  182. this._spotClickable.style.top = (Math.floor(top + canvasPos[1]) - 25 + 1) + "px";
  183. //this._spot.style["z-index"] = 90005 + Math.floor(this.viewPos[2] * 10) + 1;
  184. }
  185. },
  186.  
  187. getJSON: function () {
  188. const math = xeogl.math;
  189. const json = {
  190. primIndex: this.primIndex,
  191. bary: math.vecToArray(this.bary),
  192. offset: this.offset,
  193. occludable: this.occludable,
  194. glyph: this._glyph,
  195. pinShown: this._pinShown
  196. };
  197. if (this._attached.mesh) {
  198. json.mesh = this._attached.mesh.id;
  199. }
  200. return json;
  201. },
  202.  
  203. _destroy: function () {
  204. this._super();
  205. this.scene.off(this._tick);
  206. this._spot.parentNode.removeChild(this._spot);
  207. this._spotClickable.parentNode.removeChild(this._spotClickable);
  208. }
  209. });