aframe-extras.controls.js 55 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724
  1. (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  2. 'use strict';
  3. require('./src/controls');
  4. },{"./src/controls":7}],2:[function(require,module,exports){
  5. "use strict";
  6. module.exports = Object.assign(function GamepadButton() {}, {
  7. FACE_1: 0,
  8. FACE_2: 1,
  9. FACE_3: 2,
  10. FACE_4: 3,
  11. L_SHOULDER_1: 4,
  12. R_SHOULDER_1: 5,
  13. L_SHOULDER_2: 6,
  14. R_SHOULDER_2: 7,
  15. SELECT: 8,
  16. START: 9,
  17. DPAD_UP: 12,
  18. DPAD_DOWN: 13,
  19. DPAD_LEFT: 14,
  20. DPAD_RIGHT: 15,
  21. VENDOR: 16
  22. });
  23. },{}],3:[function(require,module,exports){
  24. "use strict";
  25. function GamepadButtonEvent(type, index, details) {
  26. this.type = type;
  27. this.index = index;
  28. this.pressed = details.pressed;
  29. this.value = details.value;
  30. }
  31. module.exports = GamepadButtonEvent;
  32. },{}],4:[function(require,module,exports){
  33. 'use strict';
  34. /**
  35. * Polyfill for the additional KeyboardEvent properties defined in the D3E and
  36. * D4E draft specifications, by @inexorabletash.
  37. *
  38. * See: https://github.com/inexorabletash/polyfill
  39. */
  40. (function (global) {
  41. var nativeKeyboardEvent = 'KeyboardEvent' in global;
  42. if (!nativeKeyboardEvent) global.KeyboardEvent = function KeyboardEvent() {
  43. throw TypeError('Illegal constructor');
  44. };
  45. if (!('DOM_KEY_LOCATION_STANDARD' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0x00; // Default or unknown location
  46. if (!('DOM_KEY_LOCATION_LEFT' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_LEFT = 0x01; // e.g. Left Alt key
  47. if (!('DOM_KEY_LOCATION_RIGHT' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 0x02; // e.g. Right Alt key
  48. if (!('DOM_KEY_LOCATION_NUMPAD' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 0x03; // e.g. Numpad 0 or +
  49. var STANDARD = window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
  50. LEFT = window.KeyboardEvent.DOM_KEY_LOCATION_LEFT,
  51. RIGHT = window.KeyboardEvent.DOM_KEY_LOCATION_RIGHT,
  52. NUMPAD = window.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
  53. //--------------------------------------------------------------------
  54. //
  55. // Utilities
  56. //
  57. //--------------------------------------------------------------------
  58. function contains(s, ss) {
  59. return String(s).indexOf(ss) !== -1;
  60. }
  61. var os = function () {
  62. if (contains(navigator.platform, 'Win')) {
  63. return 'win';
  64. }
  65. if (contains(navigator.platform, 'Mac')) {
  66. return 'mac';
  67. }
  68. if (contains(navigator.platform, 'CrOS')) {
  69. return 'cros';
  70. }
  71. if (contains(navigator.platform, 'Linux')) {
  72. return 'linux';
  73. }
  74. if (contains(navigator.userAgent, 'iPad') || contains(navigator.platform, 'iPod') || contains(navigator.platform, 'iPhone')) {
  75. return 'ios';
  76. }
  77. return '';
  78. }();
  79. var browser = function () {
  80. if (contains(navigator.userAgent, 'Chrome/')) {
  81. return 'chrome';
  82. }
  83. if (contains(navigator.vendor, 'Apple')) {
  84. return 'safari';
  85. }
  86. if (contains(navigator.userAgent, 'MSIE')) {
  87. return 'ie';
  88. }
  89. if (contains(navigator.userAgent, 'Gecko/')) {
  90. return 'moz';
  91. }
  92. if (contains(navigator.userAgent, 'Opera/')) {
  93. return 'opera';
  94. }
  95. return '';
  96. }();
  97. var browser_os = browser + '-' + os;
  98. function mergeIf(baseTable, select, table) {
  99. if (browser_os === select || browser === select || os === select) {
  100. Object.keys(table).forEach(function (keyCode) {
  101. baseTable[keyCode] = table[keyCode];
  102. });
  103. }
  104. }
  105. function remap(o, key) {
  106. var r = {};
  107. Object.keys(o).forEach(function (k) {
  108. var item = o[k];
  109. if (key in item) {
  110. r[item[key]] = item;
  111. }
  112. });
  113. return r;
  114. }
  115. function invert(o) {
  116. var r = {};
  117. Object.keys(o).forEach(function (k) {
  118. r[o[k]] = k;
  119. });
  120. return r;
  121. }
  122. //--------------------------------------------------------------------
  123. //
  124. // Generic Mappings
  125. //
  126. //--------------------------------------------------------------------
  127. // "keyInfo" is a dictionary:
  128. // code: string - name from DOM Level 3 KeyboardEvent code Values
  129. // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-code.html
  130. // location (optional): number - one of the DOM_KEY_LOCATION values
  131. // keyCap (optional): string - keyboard label in en-US locale
  132. // USB code Usage ID from page 0x07 unless otherwise noted (Informative)
  133. // Map of keyCode to keyInfo
  134. var keyCodeToInfoTable = {
  135. // 0x01 - VK_LBUTTON
  136. // 0x02 - VK_RBUTTON
  137. 0x03: { code: 'Cancel' }, // [USB: 0x9b] char \x0018 ??? (Not in D3E)
  138. // 0x04 - VK_MBUTTON
  139. // 0x05 - VK_XBUTTON1
  140. // 0x06 - VK_XBUTTON2
  141. 0x06: { code: 'Help' }, // [USB: 0x75] ???
  142. // 0x07 - undefined
  143. 0x08: { code: 'Backspace' }, // [USB: 0x2a] Labelled Delete on Macintosh keyboards.
  144. 0x09: { code: 'Tab' }, // [USB: 0x2b]
  145. // 0x0A-0x0B - reserved
  146. 0X0C: { code: 'Clear' }, // [USB: 0x9c] NumPad Center (Not in D3E)
  147. 0X0D: { code: 'Enter' }, // [USB: 0x28]
  148. // 0x0E-0x0F - undefined
  149. 0x10: { code: 'Shift' },
  150. 0x11: { code: 'Control' },
  151. 0x12: { code: 'Alt' },
  152. 0x13: { code: 'Pause' }, // [USB: 0x48]
  153. 0x14: { code: 'CapsLock' }, // [USB: 0x39]
  154. 0x15: { code: 'KanaMode' }, // [USB: 0x88] - "HangulMode" for Korean layout
  155. 0x16: { code: 'HangulMode' }, // [USB: 0x90] 0x15 as well in MSDN VK table ???
  156. 0x17: { code: 'JunjaMode' }, // (Not in D3E)
  157. 0x18: { code: 'FinalMode' }, // (Not in D3E)
  158. 0x19: { code: 'KanjiMode' }, // [USB: 0x91] - "HanjaMode" for Korean layout
  159. // 0x1A - undefined
  160. 0x1B: { code: 'Escape' }, // [USB: 0x29]
  161. 0x1C: { code: 'Convert' }, // [USB: 0x8a]
  162. 0x1D: { code: 'NonConvert' }, // [USB: 0x8b]
  163. 0x1E: { code: 'Accept' }, // (Not in D3E)
  164. 0x1F: { code: 'ModeChange' }, // (Not in D3E)
  165. 0x20: { code: 'Space' }, // [USB: 0x2c]
  166. 0x21: { code: 'PageUp' }, // [USB: 0x4b]
  167. 0x22: { code: 'PageDown' }, // [USB: 0x4e]
  168. 0x23: { code: 'End' }, // [USB: 0x4d]
  169. 0x24: { code: 'Home' }, // [USB: 0x4a]
  170. 0x25: { code: 'ArrowLeft' }, // [USB: 0x50]
  171. 0x26: { code: 'ArrowUp' }, // [USB: 0x52]
  172. 0x27: { code: 'ArrowRight' }, // [USB: 0x4f]
  173. 0x28: { code: 'ArrowDown' }, // [USB: 0x51]
  174. 0x29: { code: 'Select' }, // (Not in D3E)
  175. 0x2A: { code: 'Print' }, // (Not in D3E)
  176. 0x2B: { code: 'Execute' }, // [USB: 0x74] (Not in D3E)
  177. 0x2C: { code: 'PrintScreen' }, // [USB: 0x46]
  178. 0x2D: { code: 'Insert' }, // [USB: 0x49]
  179. 0x2E: { code: 'Delete' }, // [USB: 0x4c]
  180. 0x2F: { code: 'Help' }, // [USB: 0x75] ???
  181. 0x30: { code: 'Digit0', keyCap: '0' }, // [USB: 0x27] 0)
  182. 0x31: { code: 'Digit1', keyCap: '1' }, // [USB: 0x1e] 1!
  183. 0x32: { code: 'Digit2', keyCap: '2' }, // [USB: 0x1f] 2@
  184. 0x33: { code: 'Digit3', keyCap: '3' }, // [USB: 0x20] 3#
  185. 0x34: { code: 'Digit4', keyCap: '4' }, // [USB: 0x21] 4$
  186. 0x35: { code: 'Digit5', keyCap: '5' }, // [USB: 0x22] 5%
  187. 0x36: { code: 'Digit6', keyCap: '6' }, // [USB: 0x23] 6^
  188. 0x37: { code: 'Digit7', keyCap: '7' }, // [USB: 0x24] 7&
  189. 0x38: { code: 'Digit8', keyCap: '8' }, // [USB: 0x25] 8*
  190. 0x39: { code: 'Digit9', keyCap: '9' }, // [USB: 0x26] 9(
  191. // 0x3A-0x40 - undefined
  192. 0x41: { code: 'KeyA', keyCap: 'a' }, // [USB: 0x04]
  193. 0x42: { code: 'KeyB', keyCap: 'b' }, // [USB: 0x05]
  194. 0x43: { code: 'KeyC', keyCap: 'c' }, // [USB: 0x06]
  195. 0x44: { code: 'KeyD', keyCap: 'd' }, // [USB: 0x07]
  196. 0x45: { code: 'KeyE', keyCap: 'e' }, // [USB: 0x08]
  197. 0x46: { code: 'KeyF', keyCap: 'f' }, // [USB: 0x09]
  198. 0x47: { code: 'KeyG', keyCap: 'g' }, // [USB: 0x0a]
  199. 0x48: { code: 'KeyH', keyCap: 'h' }, // [USB: 0x0b]
  200. 0x49: { code: 'KeyI', keyCap: 'i' }, // [USB: 0x0c]
  201. 0x4A: { code: 'KeyJ', keyCap: 'j' }, // [USB: 0x0d]
  202. 0x4B: { code: 'KeyK', keyCap: 'k' }, // [USB: 0x0e]
  203. 0x4C: { code: 'KeyL', keyCap: 'l' }, // [USB: 0x0f]
  204. 0x4D: { code: 'KeyM', keyCap: 'm' }, // [USB: 0x10]
  205. 0x4E: { code: 'KeyN', keyCap: 'n' }, // [USB: 0x11]
  206. 0x4F: { code: 'KeyO', keyCap: 'o' }, // [USB: 0x12]
  207. 0x50: { code: 'KeyP', keyCap: 'p' }, // [USB: 0x13]
  208. 0x51: { code: 'KeyQ', keyCap: 'q' }, // [USB: 0x14]
  209. 0x52: { code: 'KeyR', keyCap: 'r' }, // [USB: 0x15]
  210. 0x53: { code: 'KeyS', keyCap: 's' }, // [USB: 0x16]
  211. 0x54: { code: 'KeyT', keyCap: 't' }, // [USB: 0x17]
  212. 0x55: { code: 'KeyU', keyCap: 'u' }, // [USB: 0x18]
  213. 0x56: { code: 'KeyV', keyCap: 'v' }, // [USB: 0x19]
  214. 0x57: { code: 'KeyW', keyCap: 'w' }, // [USB: 0x1a]
  215. 0x58: { code: 'KeyX', keyCap: 'x' }, // [USB: 0x1b]
  216. 0x59: { code: 'KeyY', keyCap: 'y' }, // [USB: 0x1c]
  217. 0x5A: { code: 'KeyZ', keyCap: 'z' }, // [USB: 0x1d]
  218. 0x5B: { code: 'OSLeft', location: LEFT }, // [USB: 0xe3]
  219. 0x5C: { code: 'OSRight', location: RIGHT }, // [USB: 0xe7]
  220. 0x5D: { code: 'ContextMenu' }, // [USB: 0x65] Context Menu
  221. // 0x5E - reserved
  222. 0x5F: { code: 'Standby' }, // [USB: 0x82] Sleep
  223. 0x60: { code: 'Numpad0', keyCap: '0', location: NUMPAD }, // [USB: 0x62]
  224. 0x61: { code: 'Numpad1', keyCap: '1', location: NUMPAD }, // [USB: 0x59]
  225. 0x62: { code: 'Numpad2', keyCap: '2', location: NUMPAD }, // [USB: 0x5a]
  226. 0x63: { code: 'Numpad3', keyCap: '3', location: NUMPAD }, // [USB: 0x5b]
  227. 0x64: { code: 'Numpad4', keyCap: '4', location: NUMPAD }, // [USB: 0x5c]
  228. 0x65: { code: 'Numpad5', keyCap: '5', location: NUMPAD }, // [USB: 0x5d]
  229. 0x66: { code: 'Numpad6', keyCap: '6', location: NUMPAD }, // [USB: 0x5e]
  230. 0x67: { code: 'Numpad7', keyCap: '7', location: NUMPAD }, // [USB: 0x5f]
  231. 0x68: { code: 'Numpad8', keyCap: '8', location: NUMPAD }, // [USB: 0x60]
  232. 0x69: { code: 'Numpad9', keyCap: '9', location: NUMPAD }, // [USB: 0x61]
  233. 0x6A: { code: 'NumpadMultiply', keyCap: '*', location: NUMPAD }, // [USB: 0x55]
  234. 0x6B: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD }, // [USB: 0x57]
  235. 0x6C: { code: 'NumpadComma', keyCap: ',', location: NUMPAD }, // [USB: 0x85]
  236. 0x6D: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD }, // [USB: 0x56]
  237. 0x6E: { code: 'NumpadDecimal', keyCap: '.', location: NUMPAD }, // [USB: 0x63]
  238. 0x6F: { code: 'NumpadDivide', keyCap: '/', location: NUMPAD }, // [USB: 0x54]
  239. 0x70: { code: 'F1' }, // [USB: 0x3a]
  240. 0x71: { code: 'F2' }, // [USB: 0x3b]
  241. 0x72: { code: 'F3' }, // [USB: 0x3c]
  242. 0x73: { code: 'F4' }, // [USB: 0x3d]
  243. 0x74: { code: 'F5' }, // [USB: 0x3e]
  244. 0x75: { code: 'F6' }, // [USB: 0x3f]
  245. 0x76: { code: 'F7' }, // [USB: 0x40]
  246. 0x77: { code: 'F8' }, // [USB: 0x41]
  247. 0x78: { code: 'F9' }, // [USB: 0x42]
  248. 0x79: { code: 'F10' }, // [USB: 0x43]
  249. 0x7A: { code: 'F11' }, // [USB: 0x44]
  250. 0x7B: { code: 'F12' }, // [USB: 0x45]
  251. 0x7C: { code: 'F13' }, // [USB: 0x68]
  252. 0x7D: { code: 'F14' }, // [USB: 0x69]
  253. 0x7E: { code: 'F15' }, // [USB: 0x6a]
  254. 0x7F: { code: 'F16' }, // [USB: 0x6b]
  255. 0x80: { code: 'F17' }, // [USB: 0x6c]
  256. 0x81: { code: 'F18' }, // [USB: 0x6d]
  257. 0x82: { code: 'F19' }, // [USB: 0x6e]
  258. 0x83: { code: 'F20' }, // [USB: 0x6f]
  259. 0x84: { code: 'F21' }, // [USB: 0x70]
  260. 0x85: { code: 'F22' }, // [USB: 0x71]
  261. 0x86: { code: 'F23' }, // [USB: 0x72]
  262. 0x87: { code: 'F24' }, // [USB: 0x73]
  263. // 0x88-0x8F - unassigned
  264. 0x90: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
  265. 0x91: { code: 'ScrollLock' }, // [USB: 0x47]
  266. // 0x92-0x96 - OEM specific
  267. // 0x97-0x9F - unassigned
  268. // NOTE: 0xA0-0xA5 usually mapped to 0x10-0x12 in browsers
  269. 0xA0: { code: 'ShiftLeft', location: LEFT }, // [USB: 0xe1]
  270. 0xA1: { code: 'ShiftRight', location: RIGHT }, // [USB: 0xe5]
  271. 0xA2: { code: 'ControlLeft', location: LEFT }, // [USB: 0xe0]
  272. 0xA3: { code: 'ControlRight', location: RIGHT }, // [USB: 0xe4]
  273. 0xA4: { code: 'AltLeft', location: LEFT }, // [USB: 0xe2]
  274. 0xA5: { code: 'AltRight', location: RIGHT }, // [USB: 0xe6]
  275. 0xA6: { code: 'BrowserBack' }, // [USB: 0x0c/0x0224]
  276. 0xA7: { code: 'BrowserForward' }, // [USB: 0x0c/0x0225]
  277. 0xA8: { code: 'BrowserRefresh' }, // [USB: 0x0c/0x0227]
  278. 0xA9: { code: 'BrowserStop' }, // [USB: 0x0c/0x0226]
  279. 0xAA: { code: 'BrowserSearch' }, // [USB: 0x0c/0x0221]
  280. 0xAB: { code: 'BrowserFavorites' }, // [USB: 0x0c/0x0228]
  281. 0xAC: { code: 'BrowserHome' }, // [USB: 0x0c/0x0222]
  282. 0xAD: { code: 'VolumeMute' }, // [USB: 0x7f]
  283. 0xAE: { code: 'VolumeDown' }, // [USB: 0x81]
  284. 0xAF: { code: 'VolumeUp' }, // [USB: 0x80]
  285. 0xB0: { code: 'MediaTrackNext' }, // [USB: 0x0c/0x00b5]
  286. 0xB1: { code: 'MediaTrackPrevious' }, // [USB: 0x0c/0x00b6]
  287. 0xB2: { code: 'MediaStop' }, // [USB: 0x0c/0x00b7]
  288. 0xB3: { code: 'MediaPlayPause' }, // [USB: 0x0c/0x00cd]
  289. 0xB4: { code: 'LaunchMail' }, // [USB: 0x0c/0x018a]
  290. 0xB5: { code: 'MediaSelect' },
  291. 0xB6: { code: 'LaunchApp1' },
  292. 0xB7: { code: 'LaunchApp2' },
  293. // 0xB8-0xB9 - reserved
  294. 0xBA: { code: 'Semicolon', keyCap: ';' }, // [USB: 0x33] ;: (US Standard 101)
  295. 0xBB: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
  296. 0xBC: { code: 'Comma', keyCap: ',' }, // [USB: 0x36] ,<
  297. 0xBD: { code: 'Minus', keyCap: '-' }, // [USB: 0x2d] -_
  298. 0xBE: { code: 'Period', keyCap: '.' }, // [USB: 0x37] .>
  299. 0xBF: { code: 'Slash', keyCap: '/' }, // [USB: 0x38] /? (US Standard 101)
  300. 0xC0: { code: 'Backquote', keyCap: '`' }, // [USB: 0x35] `~ (US Standard 101)
  301. // 0xC1-0xCF - reserved
  302. // 0xD0-0xD7 - reserved
  303. // 0xD8-0xDA - unassigned
  304. 0xDB: { code: 'BracketLeft', keyCap: '[' }, // [USB: 0x2f] [{ (US Standard 101)
  305. 0xDC: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
  306. 0xDD: { code: 'BracketRight', keyCap: ']' }, // [USB: 0x30] ]} (US Standard 101)
  307. 0xDE: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
  308. // 0xDF - miscellaneous/varies
  309. // 0xE0 - reserved
  310. // 0xE1 - OEM specific
  311. 0xE2: { code: 'IntlBackslash', keyCap: '\\' }, // [USB: 0x64] \| (UK Standard 102)
  312. // 0xE3-0xE4 - OEM specific
  313. 0xE5: { code: 'Process' }, // (Not in D3E)
  314. // 0xE6 - OEM specific
  315. // 0xE7 - VK_PACKET
  316. // 0xE8 - unassigned
  317. // 0xE9-0xEF - OEM specific
  318. // 0xF0-0xF5 - OEM specific
  319. 0xF6: { code: 'Attn' }, // [USB: 0x9a] (Not in D3E)
  320. 0xF7: { code: 'CrSel' }, // [USB: 0xa3] (Not in D3E)
  321. 0xF8: { code: 'ExSel' }, // [USB: 0xa4] (Not in D3E)
  322. 0xF9: { code: 'EraseEof' }, // (Not in D3E)
  323. 0xFA: { code: 'Play' }, // (Not in D3E)
  324. 0xFB: { code: 'ZoomToggle' }, // (Not in D3E)
  325. // 0xFC - VK_NONAME - reserved
  326. // 0xFD - VK_PA1
  327. 0xFE: { code: 'Clear' // [USB: 0x9c] (Not in D3E)
  328. } };
  329. // No legacy keyCode, but listed in D3E:
  330. // code: usb
  331. // 'IntlHash': 0x070032,
  332. // 'IntlRo': 0x070087,
  333. // 'IntlYen': 0x070089,
  334. // 'NumpadBackspace': 0x0700bb,
  335. // 'NumpadClear': 0x0700d8,
  336. // 'NumpadClearEntry': 0x0700d9,
  337. // 'NumpadMemoryAdd': 0x0700d3,
  338. // 'NumpadMemoryClear': 0x0700d2,
  339. // 'NumpadMemoryRecall': 0x0700d1,
  340. // 'NumpadMemoryStore': 0x0700d0,
  341. // 'NumpadMemorySubtract': 0x0700d4,
  342. // 'NumpadParenLeft': 0x0700b6,
  343. // 'NumpadParenRight': 0x0700b7,
  344. //--------------------------------------------------------------------
  345. //
  346. // Browser/OS Specific Mappings
  347. //
  348. //--------------------------------------------------------------------
  349. mergeIf(keyCodeToInfoTable, 'moz', {
  350. 0x3B: { code: 'Semicolon', keyCap: ';' }, // [USB: 0x33] ;: (US Standard 101)
  351. 0x3D: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
  352. 0x6B: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
  353. 0x6D: { code: 'Minus', keyCap: '-' }, // [USB: 0x2d] -_
  354. 0xBB: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD }, // [USB: 0x57]
  355. 0xBD: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD // [USB: 0x56]
  356. } });
  357. mergeIf(keyCodeToInfoTable, 'moz-mac', {
  358. 0x0C: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
  359. 0xAD: { code: 'Minus', keyCap: '-' // [USB: 0x2d] -_
  360. } });
  361. mergeIf(keyCodeToInfoTable, 'moz-win', {
  362. 0xAD: { code: 'Minus', keyCap: '-' // [USB: 0x2d] -_
  363. } });
  364. mergeIf(keyCodeToInfoTable, 'chrome-mac', {
  365. 0x5D: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  366. } });
  367. // Windows via Bootcamp (!)
  368. if (0) {
  369. mergeIf(keyCodeToInfoTable, 'chrome-win', {
  370. 0xC0: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
  371. 0xDE: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
  372. 0xDF: { code: 'Backquote', keyCap: '`' // [USB: 0x35] `~ (US Standard 101)
  373. } });
  374. mergeIf(keyCodeToInfoTable, 'ie', {
  375. 0xC0: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
  376. 0xDE: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
  377. 0xDF: { code: 'Backquote', keyCap: '`' // [USB: 0x35] `~ (US Standard 101)
  378. } });
  379. }
  380. mergeIf(keyCodeToInfoTable, 'safari', {
  381. 0x03: { code: 'Enter' }, // [USB: 0x28] old Safari
  382. 0x19: { code: 'Tab' // [USB: 0x2b] old Safari for Shift+Tab
  383. } });
  384. mergeIf(keyCodeToInfoTable, 'ios', {
  385. 0x0A: { code: 'Enter', location: STANDARD // [USB: 0x28]
  386. } });
  387. mergeIf(keyCodeToInfoTable, 'safari-mac', {
  388. 0x5B: { code: 'OSLeft', location: LEFT }, // [USB: 0xe3]
  389. 0x5D: { code: 'OSRight', location: RIGHT }, // [USB: 0xe7]
  390. 0xE5: { code: 'KeyQ', keyCap: 'Q' // [USB: 0x14] On alternate presses, Ctrl+Q sends this
  391. } });
  392. //--------------------------------------------------------------------
  393. //
  394. // Identifier Mappings
  395. //
  396. //--------------------------------------------------------------------
  397. // Cases where newer-ish browsers send keyIdentifier which can be
  398. // used to disambiguate keys.
  399. // keyIdentifierTable[keyIdentifier] -> keyInfo
  400. var keyIdentifierTable = {};
  401. if ('cros' === os) {
  402. keyIdentifierTable['U+00A0'] = { code: 'ShiftLeft', location: LEFT };
  403. keyIdentifierTable['U+00A1'] = { code: 'ShiftRight', location: RIGHT };
  404. keyIdentifierTable['U+00A2'] = { code: 'ControlLeft', location: LEFT };
  405. keyIdentifierTable['U+00A3'] = { code: 'ControlRight', location: RIGHT };
  406. keyIdentifierTable['U+00A4'] = { code: 'AltLeft', location: LEFT };
  407. keyIdentifierTable['U+00A5'] = { code: 'AltRight', location: RIGHT };
  408. }
  409. if ('chrome-mac' === browser_os) {
  410. keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
  411. }
  412. if ('safari-mac' === browser_os) {
  413. keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
  414. }
  415. if ('ios' === os) {
  416. // These only generate keyup events
  417. keyIdentifierTable['U+0010'] = { code: 'Function' };
  418. keyIdentifierTable['U+001C'] = { code: 'ArrowLeft' };
  419. keyIdentifierTable['U+001D'] = { code: 'ArrowRight' };
  420. keyIdentifierTable['U+001E'] = { code: 'ArrowUp' };
  421. keyIdentifierTable['U+001F'] = { code: 'ArrowDown' };
  422. keyIdentifierTable['U+0001'] = { code: 'Home' }; // [USB: 0x4a] Fn + ArrowLeft
  423. keyIdentifierTable['U+0004'] = { code: 'End' }; // [USB: 0x4d] Fn + ArrowRight
  424. keyIdentifierTable['U+000B'] = { code: 'PageUp' }; // [USB: 0x4b] Fn + ArrowUp
  425. keyIdentifierTable['U+000C'] = { code: 'PageDown' }; // [USB: 0x4e] Fn + ArrowDown
  426. }
  427. //--------------------------------------------------------------------
  428. //
  429. // Location Mappings
  430. //
  431. //--------------------------------------------------------------------
  432. // Cases where newer-ish browsers send location/keyLocation which
  433. // can be used to disambiguate keys.
  434. // locationTable[location][keyCode] -> keyInfo
  435. var locationTable = [];
  436. locationTable[LEFT] = {
  437. 0x10: { code: 'ShiftLeft', location: LEFT }, // [USB: 0xe1]
  438. 0x11: { code: 'ControlLeft', location: LEFT }, // [USB: 0xe0]
  439. 0x12: { code: 'AltLeft', location: LEFT // [USB: 0xe2]
  440. } };
  441. locationTable[RIGHT] = {
  442. 0x10: { code: 'ShiftRight', location: RIGHT }, // [USB: 0xe5]
  443. 0x11: { code: 'ControlRight', location: RIGHT }, // [USB: 0xe4]
  444. 0x12: { code: 'AltRight', location: RIGHT // [USB: 0xe6]
  445. } };
  446. locationTable[NUMPAD] = {
  447. 0x0D: { code: 'NumpadEnter', location: NUMPAD // [USB: 0x58]
  448. } };
  449. mergeIf(locationTable[NUMPAD], 'moz', {
  450. 0x6D: { code: 'NumpadSubtract', location: NUMPAD }, // [USB: 0x56]
  451. 0x6B: { code: 'NumpadAdd', location: NUMPAD // [USB: 0x57]
  452. } });
  453. mergeIf(locationTable[LEFT], 'moz-mac', {
  454. 0xE0: { code: 'OSLeft', location: LEFT // [USB: 0xe3]
  455. } });
  456. mergeIf(locationTable[RIGHT], 'moz-mac', {
  457. 0xE0: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  458. } });
  459. mergeIf(locationTable[RIGHT], 'moz-win', {
  460. 0x5B: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  461. } });
  462. mergeIf(locationTable[RIGHT], 'mac', {
  463. 0x5D: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
  464. } });
  465. mergeIf(locationTable[NUMPAD], 'chrome-mac', {
  466. 0x0C: { code: 'NumLock', location: NUMPAD // [USB: 0x53]
  467. } });
  468. mergeIf(locationTable[NUMPAD], 'safari-mac', {
  469. 0x0C: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
  470. 0xBB: { code: 'NumpadAdd', location: NUMPAD }, // [USB: 0x57]
  471. 0xBD: { code: 'NumpadSubtract', location: NUMPAD }, // [USB: 0x56]
  472. 0xBE: { code: 'NumpadDecimal', location: NUMPAD }, // [USB: 0x63]
  473. 0xBF: { code: 'NumpadDivide', location: NUMPAD // [USB: 0x54]
  474. } });
  475. //--------------------------------------------------------------------
  476. //
  477. // Key Values
  478. //
  479. //--------------------------------------------------------------------
  480. // Mapping from `code` values to `key` values. Values defined at:
  481. // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-key.html
  482. // Entries are only provided when `key` differs from `code`. If
  483. // printable, `shiftKey` has the shifted printable character. This
  484. // assumes US Standard 101 layout
  485. var codeToKeyTable = {
  486. // Modifier Keys
  487. ShiftLeft: { key: 'Shift' },
  488. ShiftRight: { key: 'Shift' },
  489. ControlLeft: { key: 'Control' },
  490. ControlRight: { key: 'Control' },
  491. AltLeft: { key: 'Alt' },
  492. AltRight: { key: 'Alt' },
  493. OSLeft: { key: 'OS' },
  494. OSRight: { key: 'OS' },
  495. // Whitespace Keys
  496. NumpadEnter: { key: 'Enter' },
  497. Space: { key: ' ' },
  498. // Printable Keys
  499. Digit0: { key: '0', shiftKey: ')' },
  500. Digit1: { key: '1', shiftKey: '!' },
  501. Digit2: { key: '2', shiftKey: '@' },
  502. Digit3: { key: '3', shiftKey: '#' },
  503. Digit4: { key: '4', shiftKey: '$' },
  504. Digit5: { key: '5', shiftKey: '%' },
  505. Digit6: { key: '6', shiftKey: '^' },
  506. Digit7: { key: '7', shiftKey: '&' },
  507. Digit8: { key: '8', shiftKey: '*' },
  508. Digit9: { key: '9', shiftKey: '(' },
  509. KeyA: { key: 'a', shiftKey: 'A' },
  510. KeyB: { key: 'b', shiftKey: 'B' },
  511. KeyC: { key: 'c', shiftKey: 'C' },
  512. KeyD: { key: 'd', shiftKey: 'D' },
  513. KeyE: { key: 'e', shiftKey: 'E' },
  514. KeyF: { key: 'f', shiftKey: 'F' },
  515. KeyG: { key: 'g', shiftKey: 'G' },
  516. KeyH: { key: 'h', shiftKey: 'H' },
  517. KeyI: { key: 'i', shiftKey: 'I' },
  518. KeyJ: { key: 'j', shiftKey: 'J' },
  519. KeyK: { key: 'k', shiftKey: 'K' },
  520. KeyL: { key: 'l', shiftKey: 'L' },
  521. KeyM: { key: 'm', shiftKey: 'M' },
  522. KeyN: { key: 'n', shiftKey: 'N' },
  523. KeyO: { key: 'o', shiftKey: 'O' },
  524. KeyP: { key: 'p', shiftKey: 'P' },
  525. KeyQ: { key: 'q', shiftKey: 'Q' },
  526. KeyR: { key: 'r', shiftKey: 'R' },
  527. KeyS: { key: 's', shiftKey: 'S' },
  528. KeyT: { key: 't', shiftKey: 'T' },
  529. KeyU: { key: 'u', shiftKey: 'U' },
  530. KeyV: { key: 'v', shiftKey: 'V' },
  531. KeyW: { key: 'w', shiftKey: 'W' },
  532. KeyX: { key: 'x', shiftKey: 'X' },
  533. KeyY: { key: 'y', shiftKey: 'Y' },
  534. KeyZ: { key: 'z', shiftKey: 'Z' },
  535. Numpad0: { key: '0' },
  536. Numpad1: { key: '1' },
  537. Numpad2: { key: '2' },
  538. Numpad3: { key: '3' },
  539. Numpad4: { key: '4' },
  540. Numpad5: { key: '5' },
  541. Numpad6: { key: '6' },
  542. Numpad7: { key: '7' },
  543. Numpad8: { key: '8' },
  544. Numpad9: { key: '9' },
  545. NumpadMultiply: { key: '*' },
  546. NumpadAdd: { key: '+' },
  547. NumpadComma: { key: ',' },
  548. NumpadSubtract: { key: '-' },
  549. NumpadDecimal: { key: '.' },
  550. NumpadDivide: { key: '/' },
  551. Semicolon: { key: ';', shiftKey: ':' },
  552. Equal: { key: '=', shiftKey: '+' },
  553. Comma: { key: ',', shiftKey: '<' },
  554. Minus: { key: '-', shiftKey: '_' },
  555. Period: { key: '.', shiftKey: '>' },
  556. Slash: { key: '/', shiftKey: '?' },
  557. Backquote: { key: '`', shiftKey: '~' },
  558. BracketLeft: { key: '[', shiftKey: '{' },
  559. Backslash: { key: '\\', shiftKey: '|' },
  560. BracketRight: { key: ']', shiftKey: '}' },
  561. Quote: { key: '\'', shiftKey: '"' },
  562. IntlBackslash: { key: '\\', shiftKey: '|' }
  563. };
  564. mergeIf(codeToKeyTable, 'mac', {
  565. OSLeft: { key: 'Meta' },
  566. OSRight: { key: 'Meta' }
  567. });
  568. // Corrections for 'key' names in older browsers (e.g. FF36-)
  569. // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.key#Key_values
  570. var keyFixTable = {
  571. Esc: 'Escape',
  572. Nonconvert: 'NonConvert',
  573. Left: 'ArrowLeft',
  574. Up: 'ArrowUp',
  575. Right: 'ArrowRight',
  576. Down: 'ArrowDown',
  577. Del: 'Delete',
  578. Menu: 'ContextMenu',
  579. MediaNextTrack: 'MediaTrackNext',
  580. MediaPreviousTrack: 'MediaTrackPrevious',
  581. SelectMedia: 'MediaSelect',
  582. HalfWidth: 'Hankaku',
  583. FullWidth: 'Zenkaku',
  584. RomanCharacters: 'Romaji',
  585. Crsel: 'CrSel',
  586. Exsel: 'ExSel',
  587. Zoom: 'ZoomToggle'
  588. };
  589. //--------------------------------------------------------------------
  590. //
  591. // Exported Functions
  592. //
  593. //--------------------------------------------------------------------
  594. var codeTable = remap(keyCodeToInfoTable, 'code');
  595. try {
  596. var nativeLocation = nativeKeyboardEvent && 'location' in new KeyboardEvent('');
  597. } catch (_) {}
  598. function keyInfoForEvent(event) {
  599. var keyCode = 'keyCode' in event ? event.keyCode : 'which' in event ? event.which : 0;
  600. var keyInfo = function () {
  601. if (nativeLocation || 'keyLocation' in event) {
  602. var location = nativeLocation ? event.location : event.keyLocation;
  603. if (location && keyCode in locationTable[location]) {
  604. return locationTable[location][keyCode];
  605. }
  606. }
  607. if ('keyIdentifier' in event && event.keyIdentifier in keyIdentifierTable) {
  608. return keyIdentifierTable[event.keyIdentifier];
  609. }
  610. if (keyCode in keyCodeToInfoTable) {
  611. return keyCodeToInfoTable[keyCode];
  612. }
  613. return null;
  614. }();
  615. // TODO: Track these down and move to general tables
  616. if (0) {
  617. // TODO: Map these for newerish browsers?
  618. // TODO: iOS only?
  619. // TODO: Override with more common keyIdentifier name?
  620. switch (event.keyIdentifier) {
  621. case 'U+0010':
  622. keyInfo = { code: 'Function' };break;
  623. case 'U+001C':
  624. keyInfo = { code: 'ArrowLeft' };break;
  625. case 'U+001D':
  626. keyInfo = { code: 'ArrowRight' };break;
  627. case 'U+001E':
  628. keyInfo = { code: 'ArrowUp' };break;
  629. case 'U+001F':
  630. keyInfo = { code: 'ArrowDown' };break;
  631. }
  632. }
  633. if (!keyInfo) return null;
  634. var key = function () {
  635. var entry = codeToKeyTable[keyInfo.code];
  636. if (!entry) return keyInfo.code;
  637. return event.shiftKey && 'shiftKey' in entry ? entry.shiftKey : entry.key;
  638. }();
  639. return {
  640. code: keyInfo.code,
  641. key: key,
  642. location: keyInfo.location,
  643. keyCap: keyInfo.keyCap
  644. };
  645. }
  646. function queryKeyCap(code, locale) {
  647. code = String(code);
  648. if (!codeTable.hasOwnProperty(code)) return 'Undefined';
  649. if (locale && String(locale).toLowerCase() !== 'en-us') throw Error('Unsupported locale');
  650. var keyInfo = codeTable[code];
  651. return keyInfo.keyCap || keyInfo.code || 'Undefined';
  652. }
  653. if ('KeyboardEvent' in global && 'defineProperty' in Object) {
  654. (function () {
  655. function define(o, p, v) {
  656. if (p in o) return;
  657. Object.defineProperty(o, p, v);
  658. }
  659. define(KeyboardEvent.prototype, 'code', { get: function get() {
  660. var keyInfo = keyInfoForEvent(this);
  661. return keyInfo ? keyInfo.code : '';
  662. } });
  663. // Fix for nonstandard `key` values (FF36-)
  664. if ('key' in KeyboardEvent.prototype) {
  665. var desc = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, 'key');
  666. Object.defineProperty(KeyboardEvent.prototype, 'key', { get: function get() {
  667. var key = desc.get.call(this);
  668. return keyFixTable.hasOwnProperty(key) ? keyFixTable[key] : key;
  669. } });
  670. }
  671. define(KeyboardEvent.prototype, 'key', { get: function get() {
  672. var keyInfo = keyInfoForEvent(this);
  673. return keyInfo && 'key' in keyInfo ? keyInfo.key : 'Unidentified';
  674. } });
  675. define(KeyboardEvent.prototype, 'location', { get: function get() {
  676. var keyInfo = keyInfoForEvent(this);
  677. return keyInfo && 'location' in keyInfo ? keyInfo.location : STANDARD;
  678. } });
  679. define(KeyboardEvent.prototype, 'locale', { get: function get() {
  680. return '';
  681. } });
  682. })();
  683. }
  684. if (!('queryKeyCap' in global.KeyboardEvent)) global.KeyboardEvent.queryKeyCap = queryKeyCap;
  685. // Helper for IE8-
  686. global.identifyKey = function (event) {
  687. if ('code' in event) return;
  688. var keyInfo = keyInfoForEvent(event);
  689. event.code = keyInfo ? keyInfo.code : '';
  690. event.key = keyInfo && 'key' in keyInfo ? keyInfo.key : 'Unidentified';
  691. event.location = 'location' in event ? event.location : 'keyLocation' in event ? event.keyLocation : keyInfo && 'location' in keyInfo ? keyInfo.location : STANDARD;
  692. event.locale = '';
  693. };
  694. })(window);
  695. },{}],5:[function(require,module,exports){
  696. 'use strict';
  697. var EPS = 0.1;
  698. module.exports = AFRAME.registerComponent('checkpoint-controls', {
  699. schema: {
  700. enabled: { default: true },
  701. mode: { default: 'teleport', oneOf: ['teleport', 'animate'] },
  702. animateSpeed: { default: 3.0 }
  703. },
  704. init: function init() {
  705. this.active = true;
  706. this.checkpoint = null;
  707. this.isNavMeshConstrained = false;
  708. this.offset = new THREE.Vector3();
  709. this.position = new THREE.Vector3();
  710. this.targetPosition = new THREE.Vector3();
  711. },
  712. play: function play() {
  713. this.active = true;
  714. },
  715. pause: function pause() {
  716. this.active = false;
  717. },
  718. setCheckpoint: function setCheckpoint(checkpoint) {
  719. var el = this.el;
  720. if (!this.active) return;
  721. if (this.checkpoint === checkpoint) return;
  722. if (this.checkpoint) {
  723. el.emit('navigation-end', { checkpoint: this.checkpoint });
  724. }
  725. this.checkpoint = checkpoint;
  726. this.sync();
  727. // Ignore new checkpoint if we're already there.
  728. if (this.position.distanceTo(this.targetPosition) < EPS) {
  729. this.checkpoint = null;
  730. return;
  731. }
  732. el.emit('navigation-start', { checkpoint: checkpoint });
  733. if (this.data.mode === 'teleport') {
  734. this.el.setAttribute('position', this.targetPosition);
  735. this.checkpoint = null;
  736. el.emit('navigation-end', { checkpoint: checkpoint });
  737. el.components['movement-controls'].updateNavLocation();
  738. }
  739. },
  740. isVelocityActive: function isVelocityActive() {
  741. return !!(this.active && this.checkpoint);
  742. },
  743. getVelocity: function getVelocity() {
  744. if (!this.active) return;
  745. var data = this.data;
  746. var offset = this.offset;
  747. var position = this.position;
  748. var targetPosition = this.targetPosition;
  749. var checkpoint = this.checkpoint;
  750. this.sync();
  751. if (position.distanceTo(targetPosition) < EPS) {
  752. this.checkpoint = null;
  753. this.el.emit('navigation-end', { checkpoint: checkpoint });
  754. return offset.set(0, 0, 0);
  755. }
  756. offset.setLength(data.animateSpeed);
  757. return offset;
  758. },
  759. sync: function sync() {
  760. var offset = this.offset;
  761. var position = this.position;
  762. var targetPosition = this.targetPosition;
  763. position.copy(this.el.getAttribute('position'));
  764. targetPosition.copy(this.checkpoint.object3D.getWorldPosition());
  765. targetPosition.add(this.checkpoint.components.checkpoint.getOffset());
  766. offset.copy(targetPosition).sub(position);
  767. }
  768. });
  769. },{}],6:[function(require,module,exports){
  770. 'use strict';
  771. /**
  772. * Gamepad controls for A-Frame.
  773. *
  774. * Stripped-down version of: https://github.com/donmccurdy/aframe-gamepad-controls
  775. *
  776. * For more information about the Gamepad API, see:
  777. * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
  778. */
  779. var GamepadButton = require('../../lib/GamepadButton'),
  780. GamepadButtonEvent = require('../../lib/GamepadButtonEvent');
  781. var JOYSTICK_EPS = 0.2;
  782. module.exports = AFRAME.registerComponent('gamepad-controls', {
  783. /*******************************************************************
  784. * Statics
  785. */
  786. GamepadButton: GamepadButton,
  787. /*******************************************************************
  788. * Schema
  789. */
  790. schema: {
  791. // Controller 0-3
  792. controller: { default: 0, oneOf: [0, 1, 2, 3] },
  793. // Enable/disable features
  794. enabled: { default: true },
  795. // Debugging
  796. debug: { default: false },
  797. // Heading element for rotation
  798. camera: { default: '[camera]', type: 'selector' },
  799. // Rotation sensitivity
  800. rotationSensitivity: { default: 2.0 }
  801. },
  802. /*******************************************************************
  803. * Core
  804. */
  805. /**
  806. * Called once when component is attached. Generally for initial setup.
  807. */
  808. init: function init() {
  809. var scene = this.el.sceneEl;
  810. this.prevTime = window.performance.now();
  811. // Button state
  812. this.buttons = {};
  813. // Rotation
  814. var rotation = this.el.object3D.rotation;
  815. this.pitch = new THREE.Object3D();
  816. this.pitch.rotation.x = THREE.Math.degToRad(rotation.x);
  817. this.yaw = new THREE.Object3D();
  818. this.yaw.position.y = 10;
  819. this.yaw.rotation.y = THREE.Math.degToRad(rotation.y);
  820. this.yaw.add(this.pitch);
  821. scene.addBehavior(this);
  822. },
  823. /**
  824. * Called when component is attached and when component data changes.
  825. * Generally modifies the entity based on the data.
  826. */
  827. update: function update() {
  828. this.tick();
  829. },
  830. /**
  831. * Called on each iteration of main render loop.
  832. */
  833. tick: function tick(t, dt) {
  834. this.updateButtonState();
  835. this.updateRotation(dt);
  836. },
  837. /**
  838. * Called when a component is removed (e.g., via removeAttribute).
  839. * Generally undoes all modifications to the entity.
  840. */
  841. remove: function remove() {},
  842. /*******************************************************************
  843. * Movement
  844. */
  845. isVelocityActive: function isVelocityActive() {
  846. if (!this.data.enabled || !this.isConnected()) return false;
  847. var dpad = this.getDpad(),
  848. joystick0 = this.getJoystick(0),
  849. inputX = dpad.x || joystick0.x,
  850. inputY = dpad.y || joystick0.y;
  851. return Math.abs(inputX) > JOYSTICK_EPS || Math.abs(inputY) > JOYSTICK_EPS;
  852. },
  853. getVelocityDelta: function getVelocityDelta() {
  854. var dpad = this.getDpad(),
  855. joystick0 = this.getJoystick(0),
  856. inputX = dpad.x || joystick0.x,
  857. inputY = dpad.y || joystick0.y,
  858. dVelocity = new THREE.Vector3();
  859. if (Math.abs(inputX) > JOYSTICK_EPS) {
  860. dVelocity.x += inputX;
  861. }
  862. if (Math.abs(inputY) > JOYSTICK_EPS) {
  863. dVelocity.z += inputY;
  864. }
  865. return dVelocity;
  866. },
  867. /*******************************************************************
  868. * Rotation
  869. */
  870. isRotationActive: function isRotationActive() {
  871. if (!this.data.enabled || !this.isConnected()) return false;
  872. var joystick1 = this.getJoystick(1);
  873. return Math.abs(joystick1.x) > JOYSTICK_EPS || Math.abs(joystick1.y) > JOYSTICK_EPS;
  874. },
  875. updateRotation: function updateRotation(dt) {
  876. if (!this.isRotationActive()) return;
  877. var data = this.data;
  878. var yaw = this.yaw;
  879. var pitch = this.pitch;
  880. var lookControls = data.camera.components['look-controls'];
  881. var hasLookControls = lookControls && lookControls.pitchObject && lookControls.yawObject;
  882. // Sync with look-controls pitch/yaw if available.
  883. if (hasLookControls) {
  884. pitch.rotation.copy(lookControls.pitchObject.rotation);
  885. yaw.rotation.copy(lookControls.yawObject.rotation);
  886. }
  887. var lookVector = this.getJoystick(1);
  888. if (Math.abs(lookVector.x) <= JOYSTICK_EPS) lookVector.x = 0;
  889. if (Math.abs(lookVector.y) <= JOYSTICK_EPS) lookVector.y = 0;
  890. lookVector.multiplyScalar(data.rotationSensitivity * dt / 1000);
  891. yaw.rotation.y -= lookVector.x;
  892. pitch.rotation.x -= lookVector.y;
  893. pitch.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, pitch.rotation.x));
  894. data.camera.object3D.rotation.set(pitch.rotation.x, yaw.rotation.y, 0);
  895. // Sync with look-controls pitch/yaw if available.
  896. if (hasLookControls) {
  897. lookControls.pitchObject.rotation.copy(pitch.rotation);
  898. lookControls.yawObject.rotation.copy(yaw.rotation);
  899. }
  900. },
  901. /*******************************************************************
  902. * Button events
  903. */
  904. updateButtonState: function updateButtonState() {
  905. var gamepad = this.getGamepad();
  906. if (this.data.enabled && gamepad) {
  907. // Fire DOM events for button state changes.
  908. for (var i = 0; i < gamepad.buttons.length; i++) {
  909. if (gamepad.buttons[i].pressed && !this.buttons[i]) {
  910. this.emit(new GamepadButtonEvent('gamepadbuttondown', i, gamepad.buttons[i]));
  911. } else if (!gamepad.buttons[i].pressed && this.buttons[i]) {
  912. this.emit(new GamepadButtonEvent('gamepadbuttonup', i, gamepad.buttons[i]));
  913. }
  914. this.buttons[i] = gamepad.buttons[i].pressed;
  915. }
  916. } else if (Object.keys(this.buttons)) {
  917. // Reset state if controls are disabled or controller is lost.
  918. this.buttons = {};
  919. }
  920. },
  921. emit: function emit(event) {
  922. // Emit original event.
  923. this.el.emit(event.type, event);
  924. // Emit convenience event, identifying button index.
  925. this.el.emit(event.type + ':' + event.index, new GamepadButtonEvent(event.type, event.index, event));
  926. },
  927. /*******************************************************************
  928. * Gamepad state
  929. */
  930. /**
  931. * Returns the Gamepad instance attached to the component. If connected,
  932. * a proxy-controls component may provide access to Gamepad input from a
  933. * remote device.
  934. *
  935. * @return {Gamepad}
  936. */
  937. getGamepad: function getGamepad() {
  938. var localGamepad = navigator.getGamepads && navigator.getGamepads()[this.data.controller],
  939. proxyControls = this.el.sceneEl.components['proxy-controls'],
  940. proxyGamepad = proxyControls && proxyControls.isConnected() && proxyControls.getGamepad(this.data.controller);
  941. return proxyGamepad || localGamepad;
  942. },
  943. /**
  944. * Returns the state of the given button.
  945. * @param {number} index The button (0-N) for which to find state.
  946. * @return {GamepadButton}
  947. */
  948. getButton: function getButton(index) {
  949. return this.getGamepad().buttons[index];
  950. },
  951. /**
  952. * Returns state of the given axis. Axes are labelled 0-N, where 0-1 will
  953. * represent X/Y on the first joystick, and 2-3 X/Y on the second.
  954. * @param {number} index The axis (0-N) for which to find state.
  955. * @return {number} On the interval [-1,1].
  956. */
  957. getAxis: function getAxis(index) {
  958. return this.getGamepad().axes[index];
  959. },
  960. /**
  961. * Returns the state of the given joystick (0 or 1) as a THREE.Vector2.
  962. * @param {number} id The joystick (0, 1) for which to find state.
  963. * @return {THREE.Vector2}
  964. */
  965. getJoystick: function getJoystick(index) {
  966. var gamepad = this.getGamepad();
  967. switch (index) {
  968. case 0:
  969. return new THREE.Vector2(gamepad.axes[0], gamepad.axes[1]);
  970. case 1:
  971. return new THREE.Vector2(gamepad.axes[2], gamepad.axes[3]);
  972. default:
  973. throw new Error('Unexpected joystick index "%d".', index);
  974. }
  975. },
  976. /**
  977. * Returns the state of the dpad as a THREE.Vector2.
  978. * @return {THREE.Vector2}
  979. */
  980. getDpad: function getDpad() {
  981. var gamepad = this.getGamepad();
  982. if (!gamepad.buttons[GamepadButton.DPAD_RIGHT]) {
  983. return new THREE.Vector2();
  984. }
  985. return new THREE.Vector2((gamepad.buttons[GamepadButton.DPAD_RIGHT].pressed ? 1 : 0) + (gamepad.buttons[GamepadButton.DPAD_LEFT].pressed ? -1 : 0), (gamepad.buttons[GamepadButton.DPAD_UP].pressed ? -1 : 0) + (gamepad.buttons[GamepadButton.DPAD_DOWN].pressed ? 1 : 0));
  986. },
  987. /**
  988. * Returns true if the gamepad is currently connected to the system.
  989. * @return {boolean}
  990. */
  991. isConnected: function isConnected() {
  992. var gamepad = this.getGamepad();
  993. return !!(gamepad && gamepad.connected);
  994. },
  995. /**
  996. * Returns a string containing some information about the controller. Result
  997. * may vary across browsers, for a given controller.
  998. * @return {string}
  999. */
  1000. getID: function getID() {
  1001. return this.getGamepad().id;
  1002. }
  1003. });
  1004. },{"../../lib/GamepadButton":2,"../../lib/GamepadButtonEvent":3}],7:[function(require,module,exports){
  1005. 'use strict';
  1006. require('./checkpoint-controls');
  1007. require('./gamepad-controls');
  1008. require('./keyboard-controls');
  1009. require('./touch-controls');
  1010. require('./movement-controls');
  1011. require('./trackpad-controls');
  1012. },{"./checkpoint-controls":5,"./gamepad-controls":6,"./keyboard-controls":8,"./movement-controls":9,"./touch-controls":10,"./trackpad-controls":11}],8:[function(require,module,exports){
  1013. 'use strict';
  1014. require('../../lib/keyboard.polyfill');
  1015. var MAX_DELTA = 0.2,
  1016. PROXY_FLAG = '__keyboard-controls-proxy';
  1017. var KeyboardEvent = window.KeyboardEvent;
  1018. /**
  1019. * Keyboard Controls component.
  1020. *
  1021. * Stripped-down version of: https://github.com/donmccurdy/aframe-keyboard-controls
  1022. *
  1023. * Bind keyboard events to components, or control your entities with the WASD keys.
  1024. *
  1025. * Why use KeyboardEvent.code? "This is set to a string representing the key that was pressed to
  1026. * generate the KeyboardEvent, without taking the current keyboard layout (e.g., QWERTY vs.
  1027. * Dvorak), locale (e.g., English vs. French), or any modifier keys into account. This is useful
  1028. * when you care about which physical key was pressed, rather thanwhich character it corresponds
  1029. * to. For example, if you’re a writing a game, you might want a certain set of keys to move the
  1030. * player in different directions, and that mapping should ideally be independent of keyboard
  1031. * layout. See: https://developers.google.com/web/updates/2016/04/keyboardevent-keys-codes
  1032. *
  1033. * @namespace wasd-controls
  1034. * keys the entity moves and if you release it will stop. Easing simulates friction.
  1035. * to the entity when pressing the keys.
  1036. * @param {bool} [enabled=true] - To completely enable or disable the controls
  1037. */
  1038. module.exports = AFRAME.registerComponent('keyboard-controls', {
  1039. schema: {
  1040. enabled: { default: true },
  1041. debug: { default: false }
  1042. },
  1043. init: function init() {
  1044. this.dVelocity = new THREE.Vector3();
  1045. this.localKeys = {};
  1046. this.listeners = {
  1047. keydown: this.onKeyDown.bind(this),
  1048. keyup: this.onKeyUp.bind(this),
  1049. blur: this.onBlur.bind(this)
  1050. };
  1051. this.attachEventListeners();
  1052. },
  1053. /*******************************************************************
  1054. * Movement
  1055. */
  1056. isVelocityActive: function isVelocityActive() {
  1057. return this.data.enabled && !!Object.keys(this.getKeys()).length;
  1058. },
  1059. getVelocityDelta: function getVelocityDelta() {
  1060. var data = this.data,
  1061. keys = this.getKeys();
  1062. this.dVelocity.set(0, 0, 0);
  1063. if (data.enabled) {
  1064. if (keys.KeyW || keys.ArrowUp) {
  1065. this.dVelocity.z -= 1;
  1066. }
  1067. if (keys.KeyA || keys.ArrowLeft) {
  1068. this.dVelocity.x -= 1;
  1069. }
  1070. if (keys.KeyS || keys.ArrowDown) {
  1071. this.dVelocity.z += 1;
  1072. }
  1073. if (keys.KeyD || keys.ArrowRight) {
  1074. this.dVelocity.x += 1;
  1075. }
  1076. }
  1077. return this.dVelocity.clone();
  1078. },
  1079. /*******************************************************************
  1080. * Events
  1081. */
  1082. play: function play() {
  1083. this.attachEventListeners();
  1084. },
  1085. pause: function pause() {
  1086. this.removeEventListeners();
  1087. },
  1088. remove: function remove() {
  1089. this.pause();
  1090. },
  1091. attachEventListeners: function attachEventListeners() {
  1092. window.addEventListener('keydown', this.listeners.keydown, false);
  1093. window.addEventListener('keyup', this.listeners.keyup, false);
  1094. window.addEventListener('blur', this.listeners.blur, false);
  1095. },
  1096. removeEventListeners: function removeEventListeners() {
  1097. window.removeEventListener('keydown', this.listeners.keydown);
  1098. window.removeEventListener('keyup', this.listeners.keyup);
  1099. window.removeEventListener('blur', this.listeners.blur);
  1100. },
  1101. onKeyDown: function onKeyDown(event) {
  1102. if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
  1103. this.localKeys[event.code] = true;
  1104. this.emit(event);
  1105. }
  1106. },
  1107. onKeyUp: function onKeyUp(event) {
  1108. if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
  1109. delete this.localKeys[event.code];
  1110. this.emit(event);
  1111. }
  1112. },
  1113. onBlur: function onBlur() {
  1114. for (var code in this.localKeys) {
  1115. if (this.localKeys.hasOwnProperty(code)) {
  1116. delete this.localKeys[code];
  1117. }
  1118. }
  1119. },
  1120. emit: function emit(event) {
  1121. // TODO - keydown only initially?
  1122. // TODO - where the f is the spacebar
  1123. // Emit original event.
  1124. if (PROXY_FLAG in event) {
  1125. // TODO - Method never triggered.
  1126. this.el.emit(event.type, event);
  1127. }
  1128. // Emit convenience event, identifying key.
  1129. this.el.emit(event.type + ':' + event.code, new KeyboardEvent(event.type, event));
  1130. if (this.data.debug) console.log(event.type + ':' + event.code);
  1131. },
  1132. /*******************************************************************
  1133. * Accessors
  1134. */
  1135. isPressed: function isPressed(code) {
  1136. return code in this.getKeys();
  1137. },
  1138. getKeys: function getKeys() {
  1139. if (this.isProxied()) {
  1140. return this.el.sceneEl.components['proxy-controls'].getKeyboard();
  1141. }
  1142. return this.localKeys;
  1143. },
  1144. isProxied: function isProxied() {
  1145. var proxyControls = this.el.sceneEl.components['proxy-controls'];
  1146. return proxyControls && proxyControls.isConnected();
  1147. }
  1148. });
  1149. },{"../../lib/keyboard.polyfill":4}],9:[function(require,module,exports){
  1150. 'use strict';
  1151. /**
  1152. * Movement Controls
  1153. *
  1154. * @author Don McCurdy <dm@donmccurdy.com>
  1155. */
  1156. var COMPONENT_SUFFIX = '-controls',
  1157. MAX_DELTA = 0.2,
  1158. // ms
  1159. EPS = 10e-6;
  1160. module.exports = AFRAME.registerComponent('movement-controls', {
  1161. /*******************************************************************
  1162. * Schema
  1163. */
  1164. dependencies: ['rotation'],
  1165. schema: {
  1166. enabled: { default: true },
  1167. controls: { default: ['gamepad', 'trackpad', 'keyboard', 'touch'] },
  1168. speed: { default: 0.3, min: 0 },
  1169. fly: { default: false },
  1170. constrainToNavMesh: { default: false },
  1171. camera: { default: '[camera]', type: 'selector' }
  1172. },
  1173. /*******************************************************************
  1174. * Lifecycle
  1175. */
  1176. init: function init() {
  1177. var el = this.el;
  1178. this.velocityCtrl = null;
  1179. this.velocity = new THREE.Vector3();
  1180. this.heading = new THREE.Quaternion();
  1181. // Navigation
  1182. this.navGroup = null;
  1183. this.navNode = null;
  1184. if (el.sceneEl.hasLoaded) {
  1185. this.injectControls();
  1186. } else {
  1187. el.sceneEl.addEventListener('loaded', this.injectControls.bind(this));
  1188. }
  1189. },
  1190. update: function update(prevData) {
  1191. var el = this.el;
  1192. var data = this.data;
  1193. if (el.sceneEl.hasLoaded) {
  1194. this.injectControls();
  1195. }
  1196. if (data.constrainToNavMesh !== prevData.constrainToNavMesh) {
  1197. var nav = el.sceneEl.systems.nav;
  1198. data.constrainToNavMesh ? nav.addAgent(this) : nav.removeAgent(this);
  1199. }
  1200. },
  1201. injectControls: function injectControls() {
  1202. var data = this.data;
  1203. var name;
  1204. for (var i = 0; i < data.controls.length; i++) {
  1205. name = data.controls[i] + COMPONENT_SUFFIX;
  1206. if (!this.el.components[name]) {
  1207. this.el.setAttribute(name, '');
  1208. }
  1209. }
  1210. },
  1211. updateNavLocation: function updateNavLocation() {
  1212. this.navGroup = null;
  1213. this.navNode = null;
  1214. },
  1215. /*******************************************************************
  1216. * Tick
  1217. */
  1218. tick: function () {
  1219. var start = new THREE.Vector3();
  1220. var end = new THREE.Vector3();
  1221. var clampedEnd = new THREE.Vector3();
  1222. return function (t, dt) {
  1223. if (!dt) return;
  1224. var el = this.el;
  1225. var data = this.data;
  1226. if (!data.enabled) return;
  1227. this.updateVelocityCtrl();
  1228. var velocityCtrl = this.velocityCtrl;
  1229. var velocity = this.velocity;
  1230. if (!velocityCtrl) return;
  1231. // Update velocity. If FPS is too low, reset.
  1232. if (dt / 1000 > MAX_DELTA) {
  1233. velocity.set(0, 0, 0);
  1234. } else {
  1235. this.updateVelocity(dt);
  1236. }
  1237. if (data.constrainToNavMesh && velocityCtrl.isNavMeshConstrained !== false) {
  1238. if (velocity.lengthSq() < EPS) return;
  1239. start.copy(el.object3D.position);
  1240. end.copy(velocity).multiplyScalar(dt / 1000).add(start);
  1241. var nav = el.sceneEl.systems.nav;
  1242. this.navGroup = this.navGroup === null ? nav.getGroup(start) : this.navGroup;
  1243. this.navNode = this.navNode || nav.getNode(start, this.navGroup);
  1244. this.navNode = nav.clampStep(start, end, this.navGroup, this.navNode, clampedEnd);
  1245. el.object3D.position.copy(clampedEnd);
  1246. } else if (el.hasAttribute('velocity')) {
  1247. el.setAttribute('velocity', velocity);
  1248. } else {
  1249. el.object3D.position.x += velocity.x * dt / 1000;
  1250. el.object3D.position.y += velocity.y * dt / 1000;
  1251. el.object3D.position.z += velocity.z * dt / 1000;
  1252. }
  1253. };
  1254. }(),
  1255. /*******************************************************************
  1256. * Movement
  1257. */
  1258. updateVelocityCtrl: function updateVelocityCtrl() {
  1259. var data = this.data;
  1260. if (data.enabled) {
  1261. for (var i = 0, l = data.controls.length; i < l; i++) {
  1262. var control = this.el.components[data.controls[i] + COMPONENT_SUFFIX];
  1263. if (control && control.isVelocityActive()) {
  1264. this.velocityCtrl = control;
  1265. return;
  1266. }
  1267. }
  1268. this.velocityCtrl = null;
  1269. }
  1270. },
  1271. updateVelocity: function () {
  1272. var vector2 = new THREE.Vector2();
  1273. // var matrix = new THREE.Matrix4();
  1274. // var matrix2 = new THREE.Matrix4();
  1275. // var position = new THREE.Vector3();
  1276. // var quaternion = new THREE.Quaternion();
  1277. // var scale = new THREE.Vector3();
  1278. return function (dt) {
  1279. var dVelocity = void 0;
  1280. var el = this.el;
  1281. var control = this.velocityCtrl;
  1282. var velocity = this.velocity;
  1283. var data = this.data;
  1284. if (control) {
  1285. if (control.getVelocityDelta) {
  1286. dVelocity = control.getVelocityDelta(dt);
  1287. } else if (control.getVelocity) {
  1288. velocity.copy(control.getVelocity());
  1289. return;
  1290. } else if (control.getPositionDelta) {
  1291. velocity.copy(control.getPositionDelta(dt).multiplyScalar(1000 / dt));
  1292. return;
  1293. } else {
  1294. throw new Error('Incompatible movement controls: ', control);
  1295. }
  1296. }
  1297. if (el.hasAttribute('velocity') && !data.constrainToNavMesh) {
  1298. velocity.copy(this.el.getAttribute('velocity'));
  1299. }
  1300. if (dVelocity && data.enabled) {
  1301. // TODO: Handle rotated rig.
  1302. var cameraEl = data.camera;
  1303. // matrix.copy(cameraEl.object3D.matrixWorld);
  1304. // matrix2.getInverse(el.object3D.matrixWorld);
  1305. // matrix.multiply(matrix2);
  1306. // matrix.decompose(position, quaternion, scale);
  1307. // dVelocity.applyQuaternion(quaternion);
  1308. // Rotate to heading
  1309. dVelocity.applyQuaternion(cameraEl.object3D.quaternion);
  1310. var factor = dVelocity.length();
  1311. if (data.fly) {
  1312. velocity.copy(dVelocity);
  1313. velocity.multiplyScalar(this.data.speed * dt);
  1314. } else {
  1315. vector2.set(dVelocity.x, dVelocity.z);
  1316. vector2.setLength(factor * this.data.speed * dt);
  1317. velocity.x = vector2.x;
  1318. velocity.z = vector2.y;
  1319. }
  1320. }
  1321. };
  1322. }()
  1323. });
  1324. },{}],10:[function(require,module,exports){
  1325. 'use strict';
  1326. /**
  1327. * Touch-to-move-forward controls for mobile.
  1328. */
  1329. module.exports = AFRAME.registerComponent('touch-controls', {
  1330. schema: {
  1331. enabled: { default: true }
  1332. },
  1333. init: function init() {
  1334. this.dVelocity = new THREE.Vector3();
  1335. this.bindMethods();
  1336. },
  1337. play: function play() {
  1338. this.addEventListeners();
  1339. },
  1340. pause: function pause() {
  1341. this.removeEventListeners();
  1342. this.dVelocity.set(0, 0, 0);
  1343. },
  1344. remove: function remove() {
  1345. this.pause();
  1346. },
  1347. addEventListeners: function addEventListeners() {
  1348. var sceneEl = this.el.sceneEl;
  1349. var canvasEl = sceneEl.canvas;
  1350. if (!canvasEl) {
  1351. sceneEl.addEventListener('render-target-loaded', this.addEventListeners.bind(this));
  1352. return;
  1353. }
  1354. canvasEl.addEventListener('touchstart', this.onTouchStart);
  1355. canvasEl.addEventListener('touchend', this.onTouchEnd);
  1356. },
  1357. removeEventListeners: function removeEventListeners() {
  1358. var canvasEl = this.el.sceneEl && this.el.sceneEl.canvas;
  1359. if (!canvasEl) {
  1360. return;
  1361. }
  1362. canvasEl.removeEventListener('touchstart', this.onTouchStart);
  1363. canvasEl.removeEventListener('touchend', this.onTouchEnd);
  1364. },
  1365. isVelocityActive: function isVelocityActive() {
  1366. return this.data.enabled && this.isMoving;
  1367. },
  1368. getVelocityDelta: function getVelocityDelta() {
  1369. this.dVelocity.z = this.isMoving ? -1 : 0;
  1370. return this.dVelocity.clone();
  1371. },
  1372. bindMethods: function bindMethods() {
  1373. this.onTouchStart = this.onTouchStart.bind(this);
  1374. this.onTouchEnd = this.onTouchEnd.bind(this);
  1375. },
  1376. onTouchStart: function onTouchStart(e) {
  1377. this.isMoving = true;
  1378. e.preventDefault();
  1379. },
  1380. onTouchEnd: function onTouchEnd(e) {
  1381. this.isMoving = false;
  1382. e.preventDefault();
  1383. }
  1384. });
  1385. },{}],11:[function(require,module,exports){
  1386. 'use strict';
  1387. /**
  1388. * 3dof (Gear VR, Daydream) controls for mobile.
  1389. */
  1390. module.exports = AFRAME.registerComponent('trackpad-controls', {
  1391. schema: {
  1392. enabled: { default: true }
  1393. },
  1394. init: function init() {
  1395. this.dVelocity = new THREE.Vector3();
  1396. this.zVel = 0;
  1397. this.bindMethods();
  1398. },
  1399. play: function play() {
  1400. this.addEventListeners();
  1401. },
  1402. pause: function pause() {
  1403. this.removeEventListeners();
  1404. this.dVelocity.set(0, 0, 0);
  1405. },
  1406. remove: function remove() {
  1407. this.pause();
  1408. },
  1409. addEventListeners: function addEventListeners() {
  1410. var sceneEl = this.el.sceneEl;
  1411. sceneEl.addEventListener('axismove', this.onAxisMove);
  1412. sceneEl.addEventListener('trackpadtouchstart', this.onTouchStart);
  1413. sceneEl.addEventListener('trackpadtouchend', this.onTouchEnd);
  1414. },
  1415. removeEventListeners: function removeEventListeners() {
  1416. var sceneEl = this.el.sceneEl;
  1417. sceneEl.removeEventListener('axismove', this.onAxisMove);
  1418. sceneEl.removeEventListener('trackpadtouchstart', this.onTouchStart);
  1419. sceneEl.removeEventListener('trackpadtouchend', this.onTouchEnd);
  1420. },
  1421. isVelocityActive: function isVelocityActive() {
  1422. return this.data.enabled && this.isMoving;
  1423. },
  1424. getVelocityDelta: function getVelocityDelta() {
  1425. this.dVelocity.z = this.isMoving ? -this.zVel : 1;
  1426. return this.dVelocity.clone();
  1427. },
  1428. bindMethods: function bindMethods() {
  1429. this.onTouchStart = this.onTouchStart.bind(this);
  1430. this.onTouchEnd = this.onTouchEnd.bind(this);
  1431. this.onAxisMove = this.onAxisMove.bind(this);
  1432. },
  1433. onTouchStart: function onTouchStart(e) {
  1434. this.isMoving = true;
  1435. e.preventDefault();
  1436. },
  1437. onTouchEnd: function onTouchEnd(e) {
  1438. this.isMoving = false;
  1439. e.preventDefault();
  1440. },
  1441. onAxisMove: function onAxisMove(e) {
  1442. var axis_data = e.detail.axis;
  1443. if (axis_data[1] < 0) {
  1444. this.zVel = 1;
  1445. }
  1446. if (axis_data[1] > 0) {
  1447. this.zVel = -1;
  1448. }
  1449. }
  1450. });
  1451. },{}]},{},[1]);