|
@@ -1,1724 +0,0 @@
|
|
|
-(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){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-require('./src/controls');
|
|
|
-
|
|
|
-},{"./src/controls":7}],2:[function(require,module,exports){
|
|
|
-"use strict";
|
|
|
-
|
|
|
-module.exports = Object.assign(function GamepadButton() {}, {
|
|
|
- FACE_1: 0,
|
|
|
- FACE_2: 1,
|
|
|
- FACE_3: 2,
|
|
|
- FACE_4: 3,
|
|
|
-
|
|
|
- L_SHOULDER_1: 4,
|
|
|
- R_SHOULDER_1: 5,
|
|
|
- L_SHOULDER_2: 6,
|
|
|
- R_SHOULDER_2: 7,
|
|
|
-
|
|
|
- SELECT: 8,
|
|
|
- START: 9,
|
|
|
-
|
|
|
- DPAD_UP: 12,
|
|
|
- DPAD_DOWN: 13,
|
|
|
- DPAD_LEFT: 14,
|
|
|
- DPAD_RIGHT: 15,
|
|
|
-
|
|
|
- VENDOR: 16
|
|
|
-});
|
|
|
-
|
|
|
-},{}],3:[function(require,module,exports){
|
|
|
-"use strict";
|
|
|
-
|
|
|
-function GamepadButtonEvent(type, index, details) {
|
|
|
- this.type = type;
|
|
|
- this.index = index;
|
|
|
- this.pressed = details.pressed;
|
|
|
- this.value = details.value;
|
|
|
-}
|
|
|
-
|
|
|
-module.exports = GamepadButtonEvent;
|
|
|
-
|
|
|
-},{}],4:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-/**
|
|
|
- * Polyfill for the additional KeyboardEvent properties defined in the D3E and
|
|
|
- * D4E draft specifications, by @inexorabletash.
|
|
|
- *
|
|
|
- * See: https://github.com/inexorabletash/polyfill
|
|
|
- */
|
|
|
-
|
|
|
-(function (global) {
|
|
|
- var nativeKeyboardEvent = 'KeyboardEvent' in global;
|
|
|
- if (!nativeKeyboardEvent) global.KeyboardEvent = function KeyboardEvent() {
|
|
|
- throw TypeError('Illegal constructor');
|
|
|
- };
|
|
|
-
|
|
|
- if (!('DOM_KEY_LOCATION_STANDARD' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_STANDARD = 0x00; // Default or unknown location
|
|
|
- if (!('DOM_KEY_LOCATION_LEFT' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_LEFT = 0x01; // e.g. Left Alt key
|
|
|
- if (!('DOM_KEY_LOCATION_RIGHT' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_RIGHT = 0x02; // e.g. Right Alt key
|
|
|
- if (!('DOM_KEY_LOCATION_NUMPAD' in global.KeyboardEvent)) global.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD = 0x03; // e.g. Numpad 0 or +
|
|
|
-
|
|
|
- var STANDARD = window.KeyboardEvent.DOM_KEY_LOCATION_STANDARD,
|
|
|
- LEFT = window.KeyboardEvent.DOM_KEY_LOCATION_LEFT,
|
|
|
- RIGHT = window.KeyboardEvent.DOM_KEY_LOCATION_RIGHT,
|
|
|
- NUMPAD = window.KeyboardEvent.DOM_KEY_LOCATION_NUMPAD;
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Utilities
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
- function contains(s, ss) {
|
|
|
- return String(s).indexOf(ss) !== -1;
|
|
|
- }
|
|
|
-
|
|
|
- var os = function () {
|
|
|
- if (contains(navigator.platform, 'Win')) {
|
|
|
- return 'win';
|
|
|
- }
|
|
|
- if (contains(navigator.platform, 'Mac')) {
|
|
|
- return 'mac';
|
|
|
- }
|
|
|
- if (contains(navigator.platform, 'CrOS')) {
|
|
|
- return 'cros';
|
|
|
- }
|
|
|
- if (contains(navigator.platform, 'Linux')) {
|
|
|
- return 'linux';
|
|
|
- }
|
|
|
- if (contains(navigator.userAgent, 'iPad') || contains(navigator.platform, 'iPod') || contains(navigator.platform, 'iPhone')) {
|
|
|
- return 'ios';
|
|
|
- }
|
|
|
- return '';
|
|
|
- }();
|
|
|
-
|
|
|
- var browser = function () {
|
|
|
- if (contains(navigator.userAgent, 'Chrome/')) {
|
|
|
- return 'chrome';
|
|
|
- }
|
|
|
- if (contains(navigator.vendor, 'Apple')) {
|
|
|
- return 'safari';
|
|
|
- }
|
|
|
- if (contains(navigator.userAgent, 'MSIE')) {
|
|
|
- return 'ie';
|
|
|
- }
|
|
|
- if (contains(navigator.userAgent, 'Gecko/')) {
|
|
|
- return 'moz';
|
|
|
- }
|
|
|
- if (contains(navigator.userAgent, 'Opera/')) {
|
|
|
- return 'opera';
|
|
|
- }
|
|
|
- return '';
|
|
|
- }();
|
|
|
-
|
|
|
- var browser_os = browser + '-' + os;
|
|
|
-
|
|
|
- function mergeIf(baseTable, select, table) {
|
|
|
- if (browser_os === select || browser === select || os === select) {
|
|
|
- Object.keys(table).forEach(function (keyCode) {
|
|
|
- baseTable[keyCode] = table[keyCode];
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- function remap(o, key) {
|
|
|
- var r = {};
|
|
|
- Object.keys(o).forEach(function (k) {
|
|
|
- var item = o[k];
|
|
|
- if (key in item) {
|
|
|
- r[item[key]] = item;
|
|
|
- }
|
|
|
- });
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
- function invert(o) {
|
|
|
- var r = {};
|
|
|
- Object.keys(o).forEach(function (k) {
|
|
|
- r[o[k]] = k;
|
|
|
- });
|
|
|
- return r;
|
|
|
- }
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Generic Mappings
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
- // "keyInfo" is a dictionary:
|
|
|
- // code: string - name from DOM Level 3 KeyboardEvent code Values
|
|
|
- // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-code.html
|
|
|
- // location (optional): number - one of the DOM_KEY_LOCATION values
|
|
|
- // keyCap (optional): string - keyboard label in en-US locale
|
|
|
- // USB code Usage ID from page 0x07 unless otherwise noted (Informative)
|
|
|
-
|
|
|
- // Map of keyCode to keyInfo
|
|
|
- var keyCodeToInfoTable = {
|
|
|
- // 0x01 - VK_LBUTTON
|
|
|
- // 0x02 - VK_RBUTTON
|
|
|
- 0x03: { code: 'Cancel' }, // [USB: 0x9b] char \x0018 ??? (Not in D3E)
|
|
|
- // 0x04 - VK_MBUTTON
|
|
|
- // 0x05 - VK_XBUTTON1
|
|
|
- // 0x06 - VK_XBUTTON2
|
|
|
- 0x06: { code: 'Help' }, // [USB: 0x75] ???
|
|
|
- // 0x07 - undefined
|
|
|
- 0x08: { code: 'Backspace' }, // [USB: 0x2a] Labelled Delete on Macintosh keyboards.
|
|
|
- 0x09: { code: 'Tab' }, // [USB: 0x2b]
|
|
|
- // 0x0A-0x0B - reserved
|
|
|
- 0X0C: { code: 'Clear' }, // [USB: 0x9c] NumPad Center (Not in D3E)
|
|
|
- 0X0D: { code: 'Enter' }, // [USB: 0x28]
|
|
|
- // 0x0E-0x0F - undefined
|
|
|
-
|
|
|
- 0x10: { code: 'Shift' },
|
|
|
- 0x11: { code: 'Control' },
|
|
|
- 0x12: { code: 'Alt' },
|
|
|
- 0x13: { code: 'Pause' }, // [USB: 0x48]
|
|
|
- 0x14: { code: 'CapsLock' }, // [USB: 0x39]
|
|
|
- 0x15: { code: 'KanaMode' }, // [USB: 0x88] - "HangulMode" for Korean layout
|
|
|
- 0x16: { code: 'HangulMode' }, // [USB: 0x90] 0x15 as well in MSDN VK table ???
|
|
|
- 0x17: { code: 'JunjaMode' }, // (Not in D3E)
|
|
|
- 0x18: { code: 'FinalMode' }, // (Not in D3E)
|
|
|
- 0x19: { code: 'KanjiMode' }, // [USB: 0x91] - "HanjaMode" for Korean layout
|
|
|
- // 0x1A - undefined
|
|
|
- 0x1B: { code: 'Escape' }, // [USB: 0x29]
|
|
|
- 0x1C: { code: 'Convert' }, // [USB: 0x8a]
|
|
|
- 0x1D: { code: 'NonConvert' }, // [USB: 0x8b]
|
|
|
- 0x1E: { code: 'Accept' }, // (Not in D3E)
|
|
|
- 0x1F: { code: 'ModeChange' }, // (Not in D3E)
|
|
|
-
|
|
|
- 0x20: { code: 'Space' }, // [USB: 0x2c]
|
|
|
- 0x21: { code: 'PageUp' }, // [USB: 0x4b]
|
|
|
- 0x22: { code: 'PageDown' }, // [USB: 0x4e]
|
|
|
- 0x23: { code: 'End' }, // [USB: 0x4d]
|
|
|
- 0x24: { code: 'Home' }, // [USB: 0x4a]
|
|
|
- 0x25: { code: 'ArrowLeft' }, // [USB: 0x50]
|
|
|
- 0x26: { code: 'ArrowUp' }, // [USB: 0x52]
|
|
|
- 0x27: { code: 'ArrowRight' }, // [USB: 0x4f]
|
|
|
- 0x28: { code: 'ArrowDown' }, // [USB: 0x51]
|
|
|
- 0x29: { code: 'Select' }, // (Not in D3E)
|
|
|
- 0x2A: { code: 'Print' }, // (Not in D3E)
|
|
|
- 0x2B: { code: 'Execute' }, // [USB: 0x74] (Not in D3E)
|
|
|
- 0x2C: { code: 'PrintScreen' }, // [USB: 0x46]
|
|
|
- 0x2D: { code: 'Insert' }, // [USB: 0x49]
|
|
|
- 0x2E: { code: 'Delete' }, // [USB: 0x4c]
|
|
|
- 0x2F: { code: 'Help' }, // [USB: 0x75] ???
|
|
|
-
|
|
|
- 0x30: { code: 'Digit0', keyCap: '0' }, // [USB: 0x27] 0)
|
|
|
- 0x31: { code: 'Digit1', keyCap: '1' }, // [USB: 0x1e] 1!
|
|
|
- 0x32: { code: 'Digit2', keyCap: '2' }, // [USB: 0x1f] 2@
|
|
|
- 0x33: { code: 'Digit3', keyCap: '3' }, // [USB: 0x20] 3#
|
|
|
- 0x34: { code: 'Digit4', keyCap: '4' }, // [USB: 0x21] 4$
|
|
|
- 0x35: { code: 'Digit5', keyCap: '5' }, // [USB: 0x22] 5%
|
|
|
- 0x36: { code: 'Digit6', keyCap: '6' }, // [USB: 0x23] 6^
|
|
|
- 0x37: { code: 'Digit7', keyCap: '7' }, // [USB: 0x24] 7&
|
|
|
- 0x38: { code: 'Digit8', keyCap: '8' }, // [USB: 0x25] 8*
|
|
|
- 0x39: { code: 'Digit9', keyCap: '9' }, // [USB: 0x26] 9(
|
|
|
- // 0x3A-0x40 - undefined
|
|
|
-
|
|
|
- 0x41: { code: 'KeyA', keyCap: 'a' }, // [USB: 0x04]
|
|
|
- 0x42: { code: 'KeyB', keyCap: 'b' }, // [USB: 0x05]
|
|
|
- 0x43: { code: 'KeyC', keyCap: 'c' }, // [USB: 0x06]
|
|
|
- 0x44: { code: 'KeyD', keyCap: 'd' }, // [USB: 0x07]
|
|
|
- 0x45: { code: 'KeyE', keyCap: 'e' }, // [USB: 0x08]
|
|
|
- 0x46: { code: 'KeyF', keyCap: 'f' }, // [USB: 0x09]
|
|
|
- 0x47: { code: 'KeyG', keyCap: 'g' }, // [USB: 0x0a]
|
|
|
- 0x48: { code: 'KeyH', keyCap: 'h' }, // [USB: 0x0b]
|
|
|
- 0x49: { code: 'KeyI', keyCap: 'i' }, // [USB: 0x0c]
|
|
|
- 0x4A: { code: 'KeyJ', keyCap: 'j' }, // [USB: 0x0d]
|
|
|
- 0x4B: { code: 'KeyK', keyCap: 'k' }, // [USB: 0x0e]
|
|
|
- 0x4C: { code: 'KeyL', keyCap: 'l' }, // [USB: 0x0f]
|
|
|
- 0x4D: { code: 'KeyM', keyCap: 'm' }, // [USB: 0x10]
|
|
|
- 0x4E: { code: 'KeyN', keyCap: 'n' }, // [USB: 0x11]
|
|
|
- 0x4F: { code: 'KeyO', keyCap: 'o' }, // [USB: 0x12]
|
|
|
-
|
|
|
- 0x50: { code: 'KeyP', keyCap: 'p' }, // [USB: 0x13]
|
|
|
- 0x51: { code: 'KeyQ', keyCap: 'q' }, // [USB: 0x14]
|
|
|
- 0x52: { code: 'KeyR', keyCap: 'r' }, // [USB: 0x15]
|
|
|
- 0x53: { code: 'KeyS', keyCap: 's' }, // [USB: 0x16]
|
|
|
- 0x54: { code: 'KeyT', keyCap: 't' }, // [USB: 0x17]
|
|
|
- 0x55: { code: 'KeyU', keyCap: 'u' }, // [USB: 0x18]
|
|
|
- 0x56: { code: 'KeyV', keyCap: 'v' }, // [USB: 0x19]
|
|
|
- 0x57: { code: 'KeyW', keyCap: 'w' }, // [USB: 0x1a]
|
|
|
- 0x58: { code: 'KeyX', keyCap: 'x' }, // [USB: 0x1b]
|
|
|
- 0x59: { code: 'KeyY', keyCap: 'y' }, // [USB: 0x1c]
|
|
|
- 0x5A: { code: 'KeyZ', keyCap: 'z' }, // [USB: 0x1d]
|
|
|
- 0x5B: { code: 'OSLeft', location: LEFT }, // [USB: 0xe3]
|
|
|
- 0x5C: { code: 'OSRight', location: RIGHT }, // [USB: 0xe7]
|
|
|
- 0x5D: { code: 'ContextMenu' }, // [USB: 0x65] Context Menu
|
|
|
- // 0x5E - reserved
|
|
|
- 0x5F: { code: 'Standby' }, // [USB: 0x82] Sleep
|
|
|
-
|
|
|
- 0x60: { code: 'Numpad0', keyCap: '0', location: NUMPAD }, // [USB: 0x62]
|
|
|
- 0x61: { code: 'Numpad1', keyCap: '1', location: NUMPAD }, // [USB: 0x59]
|
|
|
- 0x62: { code: 'Numpad2', keyCap: '2', location: NUMPAD }, // [USB: 0x5a]
|
|
|
- 0x63: { code: 'Numpad3', keyCap: '3', location: NUMPAD }, // [USB: 0x5b]
|
|
|
- 0x64: { code: 'Numpad4', keyCap: '4', location: NUMPAD }, // [USB: 0x5c]
|
|
|
- 0x65: { code: 'Numpad5', keyCap: '5', location: NUMPAD }, // [USB: 0x5d]
|
|
|
- 0x66: { code: 'Numpad6', keyCap: '6', location: NUMPAD }, // [USB: 0x5e]
|
|
|
- 0x67: { code: 'Numpad7', keyCap: '7', location: NUMPAD }, // [USB: 0x5f]
|
|
|
- 0x68: { code: 'Numpad8', keyCap: '8', location: NUMPAD }, // [USB: 0x60]
|
|
|
- 0x69: { code: 'Numpad9', keyCap: '9', location: NUMPAD }, // [USB: 0x61]
|
|
|
- 0x6A: { code: 'NumpadMultiply', keyCap: '*', location: NUMPAD }, // [USB: 0x55]
|
|
|
- 0x6B: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD }, // [USB: 0x57]
|
|
|
- 0x6C: { code: 'NumpadComma', keyCap: ',', location: NUMPAD }, // [USB: 0x85]
|
|
|
- 0x6D: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD }, // [USB: 0x56]
|
|
|
- 0x6E: { code: 'NumpadDecimal', keyCap: '.', location: NUMPAD }, // [USB: 0x63]
|
|
|
- 0x6F: { code: 'NumpadDivide', keyCap: '/', location: NUMPAD }, // [USB: 0x54]
|
|
|
-
|
|
|
- 0x70: { code: 'F1' }, // [USB: 0x3a]
|
|
|
- 0x71: { code: 'F2' }, // [USB: 0x3b]
|
|
|
- 0x72: { code: 'F3' }, // [USB: 0x3c]
|
|
|
- 0x73: { code: 'F4' }, // [USB: 0x3d]
|
|
|
- 0x74: { code: 'F5' }, // [USB: 0x3e]
|
|
|
- 0x75: { code: 'F6' }, // [USB: 0x3f]
|
|
|
- 0x76: { code: 'F7' }, // [USB: 0x40]
|
|
|
- 0x77: { code: 'F8' }, // [USB: 0x41]
|
|
|
- 0x78: { code: 'F9' }, // [USB: 0x42]
|
|
|
- 0x79: { code: 'F10' }, // [USB: 0x43]
|
|
|
- 0x7A: { code: 'F11' }, // [USB: 0x44]
|
|
|
- 0x7B: { code: 'F12' }, // [USB: 0x45]
|
|
|
- 0x7C: { code: 'F13' }, // [USB: 0x68]
|
|
|
- 0x7D: { code: 'F14' }, // [USB: 0x69]
|
|
|
- 0x7E: { code: 'F15' }, // [USB: 0x6a]
|
|
|
- 0x7F: { code: 'F16' }, // [USB: 0x6b]
|
|
|
-
|
|
|
- 0x80: { code: 'F17' }, // [USB: 0x6c]
|
|
|
- 0x81: { code: 'F18' }, // [USB: 0x6d]
|
|
|
- 0x82: { code: 'F19' }, // [USB: 0x6e]
|
|
|
- 0x83: { code: 'F20' }, // [USB: 0x6f]
|
|
|
- 0x84: { code: 'F21' }, // [USB: 0x70]
|
|
|
- 0x85: { code: 'F22' }, // [USB: 0x71]
|
|
|
- 0x86: { code: 'F23' }, // [USB: 0x72]
|
|
|
- 0x87: { code: 'F24' }, // [USB: 0x73]
|
|
|
- // 0x88-0x8F - unassigned
|
|
|
-
|
|
|
- 0x90: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
|
|
|
- 0x91: { code: 'ScrollLock' }, // [USB: 0x47]
|
|
|
- // 0x92-0x96 - OEM specific
|
|
|
- // 0x97-0x9F - unassigned
|
|
|
-
|
|
|
- // NOTE: 0xA0-0xA5 usually mapped to 0x10-0x12 in browsers
|
|
|
- 0xA0: { code: 'ShiftLeft', location: LEFT }, // [USB: 0xe1]
|
|
|
- 0xA1: { code: 'ShiftRight', location: RIGHT }, // [USB: 0xe5]
|
|
|
- 0xA2: { code: 'ControlLeft', location: LEFT }, // [USB: 0xe0]
|
|
|
- 0xA3: { code: 'ControlRight', location: RIGHT }, // [USB: 0xe4]
|
|
|
- 0xA4: { code: 'AltLeft', location: LEFT }, // [USB: 0xe2]
|
|
|
- 0xA5: { code: 'AltRight', location: RIGHT }, // [USB: 0xe6]
|
|
|
-
|
|
|
- 0xA6: { code: 'BrowserBack' }, // [USB: 0x0c/0x0224]
|
|
|
- 0xA7: { code: 'BrowserForward' }, // [USB: 0x0c/0x0225]
|
|
|
- 0xA8: { code: 'BrowserRefresh' }, // [USB: 0x0c/0x0227]
|
|
|
- 0xA9: { code: 'BrowserStop' }, // [USB: 0x0c/0x0226]
|
|
|
- 0xAA: { code: 'BrowserSearch' }, // [USB: 0x0c/0x0221]
|
|
|
- 0xAB: { code: 'BrowserFavorites' }, // [USB: 0x0c/0x0228]
|
|
|
- 0xAC: { code: 'BrowserHome' }, // [USB: 0x0c/0x0222]
|
|
|
- 0xAD: { code: 'VolumeMute' }, // [USB: 0x7f]
|
|
|
- 0xAE: { code: 'VolumeDown' }, // [USB: 0x81]
|
|
|
- 0xAF: { code: 'VolumeUp' }, // [USB: 0x80]
|
|
|
-
|
|
|
- 0xB0: { code: 'MediaTrackNext' }, // [USB: 0x0c/0x00b5]
|
|
|
- 0xB1: { code: 'MediaTrackPrevious' }, // [USB: 0x0c/0x00b6]
|
|
|
- 0xB2: { code: 'MediaStop' }, // [USB: 0x0c/0x00b7]
|
|
|
- 0xB3: { code: 'MediaPlayPause' }, // [USB: 0x0c/0x00cd]
|
|
|
- 0xB4: { code: 'LaunchMail' }, // [USB: 0x0c/0x018a]
|
|
|
- 0xB5: { code: 'MediaSelect' },
|
|
|
- 0xB6: { code: 'LaunchApp1' },
|
|
|
- 0xB7: { code: 'LaunchApp2' },
|
|
|
- // 0xB8-0xB9 - reserved
|
|
|
- 0xBA: { code: 'Semicolon', keyCap: ';' }, // [USB: 0x33] ;: (US Standard 101)
|
|
|
- 0xBB: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
|
|
|
- 0xBC: { code: 'Comma', keyCap: ',' }, // [USB: 0x36] ,<
|
|
|
- 0xBD: { code: 'Minus', keyCap: '-' }, // [USB: 0x2d] -_
|
|
|
- 0xBE: { code: 'Period', keyCap: '.' }, // [USB: 0x37] .>
|
|
|
- 0xBF: { code: 'Slash', keyCap: '/' }, // [USB: 0x38] /? (US Standard 101)
|
|
|
-
|
|
|
- 0xC0: { code: 'Backquote', keyCap: '`' }, // [USB: 0x35] `~ (US Standard 101)
|
|
|
- // 0xC1-0xCF - reserved
|
|
|
-
|
|
|
- // 0xD0-0xD7 - reserved
|
|
|
- // 0xD8-0xDA - unassigned
|
|
|
- 0xDB: { code: 'BracketLeft', keyCap: '[' }, // [USB: 0x2f] [{ (US Standard 101)
|
|
|
- 0xDC: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
|
|
|
- 0xDD: { code: 'BracketRight', keyCap: ']' }, // [USB: 0x30] ]} (US Standard 101)
|
|
|
- 0xDE: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
|
|
|
- // 0xDF - miscellaneous/varies
|
|
|
-
|
|
|
- // 0xE0 - reserved
|
|
|
- // 0xE1 - OEM specific
|
|
|
- 0xE2: { code: 'IntlBackslash', keyCap: '\\' }, // [USB: 0x64] \| (UK Standard 102)
|
|
|
- // 0xE3-0xE4 - OEM specific
|
|
|
- 0xE5: { code: 'Process' }, // (Not in D3E)
|
|
|
- // 0xE6 - OEM specific
|
|
|
- // 0xE7 - VK_PACKET
|
|
|
- // 0xE8 - unassigned
|
|
|
- // 0xE9-0xEF - OEM specific
|
|
|
-
|
|
|
- // 0xF0-0xF5 - OEM specific
|
|
|
- 0xF6: { code: 'Attn' }, // [USB: 0x9a] (Not in D3E)
|
|
|
- 0xF7: { code: 'CrSel' }, // [USB: 0xa3] (Not in D3E)
|
|
|
- 0xF8: { code: 'ExSel' }, // [USB: 0xa4] (Not in D3E)
|
|
|
- 0xF9: { code: 'EraseEof' }, // (Not in D3E)
|
|
|
- 0xFA: { code: 'Play' }, // (Not in D3E)
|
|
|
- 0xFB: { code: 'ZoomToggle' }, // (Not in D3E)
|
|
|
- // 0xFC - VK_NONAME - reserved
|
|
|
- // 0xFD - VK_PA1
|
|
|
- 0xFE: { code: 'Clear' // [USB: 0x9c] (Not in D3E)
|
|
|
- } };
|
|
|
-
|
|
|
- // No legacy keyCode, but listed in D3E:
|
|
|
-
|
|
|
- // code: usb
|
|
|
- // 'IntlHash': 0x070032,
|
|
|
- // 'IntlRo': 0x070087,
|
|
|
- // 'IntlYen': 0x070089,
|
|
|
- // 'NumpadBackspace': 0x0700bb,
|
|
|
- // 'NumpadClear': 0x0700d8,
|
|
|
- // 'NumpadClearEntry': 0x0700d9,
|
|
|
- // 'NumpadMemoryAdd': 0x0700d3,
|
|
|
- // 'NumpadMemoryClear': 0x0700d2,
|
|
|
- // 'NumpadMemoryRecall': 0x0700d1,
|
|
|
- // 'NumpadMemoryStore': 0x0700d0,
|
|
|
- // 'NumpadMemorySubtract': 0x0700d4,
|
|
|
- // 'NumpadParenLeft': 0x0700b6,
|
|
|
- // 'NumpadParenRight': 0x0700b7,
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Browser/OS Specific Mappings
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'moz', {
|
|
|
- 0x3B: { code: 'Semicolon', keyCap: ';' }, // [USB: 0x33] ;: (US Standard 101)
|
|
|
- 0x3D: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
|
|
|
- 0x6B: { code: 'Equal', keyCap: '=' }, // [USB: 0x2e] =+
|
|
|
- 0x6D: { code: 'Minus', keyCap: '-' }, // [USB: 0x2d] -_
|
|
|
- 0xBB: { code: 'NumpadAdd', keyCap: '+', location: NUMPAD }, // [USB: 0x57]
|
|
|
- 0xBD: { code: 'NumpadSubtract', keyCap: '-', location: NUMPAD // [USB: 0x56]
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'moz-mac', {
|
|
|
- 0x0C: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
|
|
|
- 0xAD: { code: 'Minus', keyCap: '-' // [USB: 0x2d] -_
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'moz-win', {
|
|
|
- 0xAD: { code: 'Minus', keyCap: '-' // [USB: 0x2d] -_
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'chrome-mac', {
|
|
|
- 0x5D: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
|
|
|
- } });
|
|
|
-
|
|
|
- // Windows via Bootcamp (!)
|
|
|
- if (0) {
|
|
|
- mergeIf(keyCodeToInfoTable, 'chrome-win', {
|
|
|
- 0xC0: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
|
|
|
- 0xDE: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
|
|
|
- 0xDF: { code: 'Backquote', keyCap: '`' // [USB: 0x35] `~ (US Standard 101)
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'ie', {
|
|
|
- 0xC0: { code: 'Quote', keyCap: '\'' }, // [USB: 0x34] '" (US Standard 101)
|
|
|
- 0xDE: { code: 'Backslash', keyCap: '\\' }, // [USB: 0x31] \| (US Standard 101)
|
|
|
- 0xDF: { code: 'Backquote', keyCap: '`' // [USB: 0x35] `~ (US Standard 101)
|
|
|
- } });
|
|
|
- }
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'safari', {
|
|
|
- 0x03: { code: 'Enter' }, // [USB: 0x28] old Safari
|
|
|
- 0x19: { code: 'Tab' // [USB: 0x2b] old Safari for Shift+Tab
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'ios', {
|
|
|
- 0x0A: { code: 'Enter', location: STANDARD // [USB: 0x28]
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(keyCodeToInfoTable, 'safari-mac', {
|
|
|
- 0x5B: { code: 'OSLeft', location: LEFT }, // [USB: 0xe3]
|
|
|
- 0x5D: { code: 'OSRight', location: RIGHT }, // [USB: 0xe7]
|
|
|
- 0xE5: { code: 'KeyQ', keyCap: 'Q' // [USB: 0x14] On alternate presses, Ctrl+Q sends this
|
|
|
- } });
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Identifier Mappings
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
- // Cases where newer-ish browsers send keyIdentifier which can be
|
|
|
- // used to disambiguate keys.
|
|
|
-
|
|
|
- // keyIdentifierTable[keyIdentifier] -> keyInfo
|
|
|
-
|
|
|
- var keyIdentifierTable = {};
|
|
|
- if ('cros' === os) {
|
|
|
- keyIdentifierTable['U+00A0'] = { code: 'ShiftLeft', location: LEFT };
|
|
|
- keyIdentifierTable['U+00A1'] = { code: 'ShiftRight', location: RIGHT };
|
|
|
- keyIdentifierTable['U+00A2'] = { code: 'ControlLeft', location: LEFT };
|
|
|
- keyIdentifierTable['U+00A3'] = { code: 'ControlRight', location: RIGHT };
|
|
|
- keyIdentifierTable['U+00A4'] = { code: 'AltLeft', location: LEFT };
|
|
|
- keyIdentifierTable['U+00A5'] = { code: 'AltRight', location: RIGHT };
|
|
|
- }
|
|
|
- if ('chrome-mac' === browser_os) {
|
|
|
- keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
|
|
|
- }
|
|
|
- if ('safari-mac' === browser_os) {
|
|
|
- keyIdentifierTable['U+0010'] = { code: 'ContextMenu' };
|
|
|
- }
|
|
|
- if ('ios' === os) {
|
|
|
- // These only generate keyup events
|
|
|
- keyIdentifierTable['U+0010'] = { code: 'Function' };
|
|
|
-
|
|
|
- keyIdentifierTable['U+001C'] = { code: 'ArrowLeft' };
|
|
|
- keyIdentifierTable['U+001D'] = { code: 'ArrowRight' };
|
|
|
- keyIdentifierTable['U+001E'] = { code: 'ArrowUp' };
|
|
|
- keyIdentifierTable['U+001F'] = { code: 'ArrowDown' };
|
|
|
-
|
|
|
- keyIdentifierTable['U+0001'] = { code: 'Home' }; // [USB: 0x4a] Fn + ArrowLeft
|
|
|
- keyIdentifierTable['U+0004'] = { code: 'End' }; // [USB: 0x4d] Fn + ArrowRight
|
|
|
- keyIdentifierTable['U+000B'] = { code: 'PageUp' }; // [USB: 0x4b] Fn + ArrowUp
|
|
|
- keyIdentifierTable['U+000C'] = { code: 'PageDown' }; // [USB: 0x4e] Fn + ArrowDown
|
|
|
- }
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Location Mappings
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
- // Cases where newer-ish browsers send location/keyLocation which
|
|
|
- // can be used to disambiguate keys.
|
|
|
-
|
|
|
- // locationTable[location][keyCode] -> keyInfo
|
|
|
- var locationTable = [];
|
|
|
- locationTable[LEFT] = {
|
|
|
- 0x10: { code: 'ShiftLeft', location: LEFT }, // [USB: 0xe1]
|
|
|
- 0x11: { code: 'ControlLeft', location: LEFT }, // [USB: 0xe0]
|
|
|
- 0x12: { code: 'AltLeft', location: LEFT // [USB: 0xe2]
|
|
|
- } };
|
|
|
- locationTable[RIGHT] = {
|
|
|
- 0x10: { code: 'ShiftRight', location: RIGHT }, // [USB: 0xe5]
|
|
|
- 0x11: { code: 'ControlRight', location: RIGHT }, // [USB: 0xe4]
|
|
|
- 0x12: { code: 'AltRight', location: RIGHT // [USB: 0xe6]
|
|
|
- } };
|
|
|
- locationTable[NUMPAD] = {
|
|
|
- 0x0D: { code: 'NumpadEnter', location: NUMPAD // [USB: 0x58]
|
|
|
- } };
|
|
|
-
|
|
|
- mergeIf(locationTable[NUMPAD], 'moz', {
|
|
|
- 0x6D: { code: 'NumpadSubtract', location: NUMPAD }, // [USB: 0x56]
|
|
|
- 0x6B: { code: 'NumpadAdd', location: NUMPAD // [USB: 0x57]
|
|
|
- } });
|
|
|
- mergeIf(locationTable[LEFT], 'moz-mac', {
|
|
|
- 0xE0: { code: 'OSLeft', location: LEFT // [USB: 0xe3]
|
|
|
- } });
|
|
|
- mergeIf(locationTable[RIGHT], 'moz-mac', {
|
|
|
- 0xE0: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
|
|
|
- } });
|
|
|
- mergeIf(locationTable[RIGHT], 'moz-win', {
|
|
|
- 0x5B: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(locationTable[RIGHT], 'mac', {
|
|
|
- 0x5D: { code: 'OSRight', location: RIGHT // [USB: 0xe7]
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(locationTable[NUMPAD], 'chrome-mac', {
|
|
|
- 0x0C: { code: 'NumLock', location: NUMPAD // [USB: 0x53]
|
|
|
- } });
|
|
|
-
|
|
|
- mergeIf(locationTable[NUMPAD], 'safari-mac', {
|
|
|
- 0x0C: { code: 'NumLock', location: NUMPAD }, // [USB: 0x53]
|
|
|
- 0xBB: { code: 'NumpadAdd', location: NUMPAD }, // [USB: 0x57]
|
|
|
- 0xBD: { code: 'NumpadSubtract', location: NUMPAD }, // [USB: 0x56]
|
|
|
- 0xBE: { code: 'NumpadDecimal', location: NUMPAD }, // [USB: 0x63]
|
|
|
- 0xBF: { code: 'NumpadDivide', location: NUMPAD // [USB: 0x54]
|
|
|
- } });
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Key Values
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
- // Mapping from `code` values to `key` values. Values defined at:
|
|
|
- // https://dvcs.w3.org/hg/dom3events/raw-file/tip/html/DOM3Events-key.html
|
|
|
- // Entries are only provided when `key` differs from `code`. If
|
|
|
- // printable, `shiftKey` has the shifted printable character. This
|
|
|
- // assumes US Standard 101 layout
|
|
|
-
|
|
|
- var codeToKeyTable = {
|
|
|
- // Modifier Keys
|
|
|
- ShiftLeft: { key: 'Shift' },
|
|
|
- ShiftRight: { key: 'Shift' },
|
|
|
- ControlLeft: { key: 'Control' },
|
|
|
- ControlRight: { key: 'Control' },
|
|
|
- AltLeft: { key: 'Alt' },
|
|
|
- AltRight: { key: 'Alt' },
|
|
|
- OSLeft: { key: 'OS' },
|
|
|
- OSRight: { key: 'OS' },
|
|
|
-
|
|
|
- // Whitespace Keys
|
|
|
- NumpadEnter: { key: 'Enter' },
|
|
|
- Space: { key: ' ' },
|
|
|
-
|
|
|
- // Printable Keys
|
|
|
- Digit0: { key: '0', shiftKey: ')' },
|
|
|
- Digit1: { key: '1', shiftKey: '!' },
|
|
|
- Digit2: { key: '2', shiftKey: '@' },
|
|
|
- Digit3: { key: '3', shiftKey: '#' },
|
|
|
- Digit4: { key: '4', shiftKey: '$' },
|
|
|
- Digit5: { key: '5', shiftKey: '%' },
|
|
|
- Digit6: { key: '6', shiftKey: '^' },
|
|
|
- Digit7: { key: '7', shiftKey: '&' },
|
|
|
- Digit8: { key: '8', shiftKey: '*' },
|
|
|
- Digit9: { key: '9', shiftKey: '(' },
|
|
|
- KeyA: { key: 'a', shiftKey: 'A' },
|
|
|
- KeyB: { key: 'b', shiftKey: 'B' },
|
|
|
- KeyC: { key: 'c', shiftKey: 'C' },
|
|
|
- KeyD: { key: 'd', shiftKey: 'D' },
|
|
|
- KeyE: { key: 'e', shiftKey: 'E' },
|
|
|
- KeyF: { key: 'f', shiftKey: 'F' },
|
|
|
- KeyG: { key: 'g', shiftKey: 'G' },
|
|
|
- KeyH: { key: 'h', shiftKey: 'H' },
|
|
|
- KeyI: { key: 'i', shiftKey: 'I' },
|
|
|
- KeyJ: { key: 'j', shiftKey: 'J' },
|
|
|
- KeyK: { key: 'k', shiftKey: 'K' },
|
|
|
- KeyL: { key: 'l', shiftKey: 'L' },
|
|
|
- KeyM: { key: 'm', shiftKey: 'M' },
|
|
|
- KeyN: { key: 'n', shiftKey: 'N' },
|
|
|
- KeyO: { key: 'o', shiftKey: 'O' },
|
|
|
- KeyP: { key: 'p', shiftKey: 'P' },
|
|
|
- KeyQ: { key: 'q', shiftKey: 'Q' },
|
|
|
- KeyR: { key: 'r', shiftKey: 'R' },
|
|
|
- KeyS: { key: 's', shiftKey: 'S' },
|
|
|
- KeyT: { key: 't', shiftKey: 'T' },
|
|
|
- KeyU: { key: 'u', shiftKey: 'U' },
|
|
|
- KeyV: { key: 'v', shiftKey: 'V' },
|
|
|
- KeyW: { key: 'w', shiftKey: 'W' },
|
|
|
- KeyX: { key: 'x', shiftKey: 'X' },
|
|
|
- KeyY: { key: 'y', shiftKey: 'Y' },
|
|
|
- KeyZ: { key: 'z', shiftKey: 'Z' },
|
|
|
- Numpad0: { key: '0' },
|
|
|
- Numpad1: { key: '1' },
|
|
|
- Numpad2: { key: '2' },
|
|
|
- Numpad3: { key: '3' },
|
|
|
- Numpad4: { key: '4' },
|
|
|
- Numpad5: { key: '5' },
|
|
|
- Numpad6: { key: '6' },
|
|
|
- Numpad7: { key: '7' },
|
|
|
- Numpad8: { key: '8' },
|
|
|
- Numpad9: { key: '9' },
|
|
|
- NumpadMultiply: { key: '*' },
|
|
|
- NumpadAdd: { key: '+' },
|
|
|
- NumpadComma: { key: ',' },
|
|
|
- NumpadSubtract: { key: '-' },
|
|
|
- NumpadDecimal: { key: '.' },
|
|
|
- NumpadDivide: { key: '/' },
|
|
|
- Semicolon: { key: ';', shiftKey: ':' },
|
|
|
- Equal: { key: '=', shiftKey: '+' },
|
|
|
- Comma: { key: ',', shiftKey: '<' },
|
|
|
- Minus: { key: '-', shiftKey: '_' },
|
|
|
- Period: { key: '.', shiftKey: '>' },
|
|
|
- Slash: { key: '/', shiftKey: '?' },
|
|
|
- Backquote: { key: '`', shiftKey: '~' },
|
|
|
- BracketLeft: { key: '[', shiftKey: '{' },
|
|
|
- Backslash: { key: '\\', shiftKey: '|' },
|
|
|
- BracketRight: { key: ']', shiftKey: '}' },
|
|
|
- Quote: { key: '\'', shiftKey: '"' },
|
|
|
- IntlBackslash: { key: '\\', shiftKey: '|' }
|
|
|
- };
|
|
|
-
|
|
|
- mergeIf(codeToKeyTable, 'mac', {
|
|
|
- OSLeft: { key: 'Meta' },
|
|
|
- OSRight: { key: 'Meta' }
|
|
|
- });
|
|
|
-
|
|
|
- // Corrections for 'key' names in older browsers (e.g. FF36-)
|
|
|
- // https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent.key#Key_values
|
|
|
- var keyFixTable = {
|
|
|
- Esc: 'Escape',
|
|
|
- Nonconvert: 'NonConvert',
|
|
|
- Left: 'ArrowLeft',
|
|
|
- Up: 'ArrowUp',
|
|
|
- Right: 'ArrowRight',
|
|
|
- Down: 'ArrowDown',
|
|
|
- Del: 'Delete',
|
|
|
- Menu: 'ContextMenu',
|
|
|
- MediaNextTrack: 'MediaTrackNext',
|
|
|
- MediaPreviousTrack: 'MediaTrackPrevious',
|
|
|
- SelectMedia: 'MediaSelect',
|
|
|
- HalfWidth: 'Hankaku',
|
|
|
- FullWidth: 'Zenkaku',
|
|
|
- RomanCharacters: 'Romaji',
|
|
|
- Crsel: 'CrSel',
|
|
|
- Exsel: 'ExSel',
|
|
|
- Zoom: 'ZoomToggle'
|
|
|
- };
|
|
|
-
|
|
|
- //--------------------------------------------------------------------
|
|
|
- //
|
|
|
- // Exported Functions
|
|
|
- //
|
|
|
- //--------------------------------------------------------------------
|
|
|
-
|
|
|
-
|
|
|
- var codeTable = remap(keyCodeToInfoTable, 'code');
|
|
|
-
|
|
|
- try {
|
|
|
- var nativeLocation = nativeKeyboardEvent && 'location' in new KeyboardEvent('');
|
|
|
- } catch (_) {}
|
|
|
-
|
|
|
- function keyInfoForEvent(event) {
|
|
|
- var keyCode = 'keyCode' in event ? event.keyCode : 'which' in event ? event.which : 0;
|
|
|
-
|
|
|
- var keyInfo = function () {
|
|
|
- if (nativeLocation || 'keyLocation' in event) {
|
|
|
- var location = nativeLocation ? event.location : event.keyLocation;
|
|
|
- if (location && keyCode in locationTable[location]) {
|
|
|
- return locationTable[location][keyCode];
|
|
|
- }
|
|
|
- }
|
|
|
- if ('keyIdentifier' in event && event.keyIdentifier in keyIdentifierTable) {
|
|
|
- return keyIdentifierTable[event.keyIdentifier];
|
|
|
- }
|
|
|
- if (keyCode in keyCodeToInfoTable) {
|
|
|
- return keyCodeToInfoTable[keyCode];
|
|
|
- }
|
|
|
- return null;
|
|
|
- }();
|
|
|
-
|
|
|
- // TODO: Track these down and move to general tables
|
|
|
- if (0) {
|
|
|
- // TODO: Map these for newerish browsers?
|
|
|
- // TODO: iOS only?
|
|
|
- // TODO: Override with more common keyIdentifier name?
|
|
|
- switch (event.keyIdentifier) {
|
|
|
- case 'U+0010':
|
|
|
- keyInfo = { code: 'Function' };break;
|
|
|
- case 'U+001C':
|
|
|
- keyInfo = { code: 'ArrowLeft' };break;
|
|
|
- case 'U+001D':
|
|
|
- keyInfo = { code: 'ArrowRight' };break;
|
|
|
- case 'U+001E':
|
|
|
- keyInfo = { code: 'ArrowUp' };break;
|
|
|
- case 'U+001F':
|
|
|
- keyInfo = { code: 'ArrowDown' };break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (!keyInfo) return null;
|
|
|
-
|
|
|
- var key = function () {
|
|
|
- var entry = codeToKeyTable[keyInfo.code];
|
|
|
- if (!entry) return keyInfo.code;
|
|
|
- return event.shiftKey && 'shiftKey' in entry ? entry.shiftKey : entry.key;
|
|
|
- }();
|
|
|
-
|
|
|
- return {
|
|
|
- code: keyInfo.code,
|
|
|
- key: key,
|
|
|
- location: keyInfo.location,
|
|
|
- keyCap: keyInfo.keyCap
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- function queryKeyCap(code, locale) {
|
|
|
- code = String(code);
|
|
|
- if (!codeTable.hasOwnProperty(code)) return 'Undefined';
|
|
|
- if (locale && String(locale).toLowerCase() !== 'en-us') throw Error('Unsupported locale');
|
|
|
- var keyInfo = codeTable[code];
|
|
|
- return keyInfo.keyCap || keyInfo.code || 'Undefined';
|
|
|
- }
|
|
|
-
|
|
|
- if ('KeyboardEvent' in global && 'defineProperty' in Object) {
|
|
|
- (function () {
|
|
|
- function define(o, p, v) {
|
|
|
- if (p in o) return;
|
|
|
- Object.defineProperty(o, p, v);
|
|
|
- }
|
|
|
-
|
|
|
- define(KeyboardEvent.prototype, 'code', { get: function get() {
|
|
|
- var keyInfo = keyInfoForEvent(this);
|
|
|
- return keyInfo ? keyInfo.code : '';
|
|
|
- } });
|
|
|
-
|
|
|
- // Fix for nonstandard `key` values (FF36-)
|
|
|
- if ('key' in KeyboardEvent.prototype) {
|
|
|
- var desc = Object.getOwnPropertyDescriptor(KeyboardEvent.prototype, 'key');
|
|
|
- Object.defineProperty(KeyboardEvent.prototype, 'key', { get: function get() {
|
|
|
- var key = desc.get.call(this);
|
|
|
- return keyFixTable.hasOwnProperty(key) ? keyFixTable[key] : key;
|
|
|
- } });
|
|
|
- }
|
|
|
-
|
|
|
- define(KeyboardEvent.prototype, 'key', { get: function get() {
|
|
|
- var keyInfo = keyInfoForEvent(this);
|
|
|
- return keyInfo && 'key' in keyInfo ? keyInfo.key : 'Unidentified';
|
|
|
- } });
|
|
|
-
|
|
|
- define(KeyboardEvent.prototype, 'location', { get: function get() {
|
|
|
- var keyInfo = keyInfoForEvent(this);
|
|
|
- return keyInfo && 'location' in keyInfo ? keyInfo.location : STANDARD;
|
|
|
- } });
|
|
|
-
|
|
|
- define(KeyboardEvent.prototype, 'locale', { get: function get() {
|
|
|
- return '';
|
|
|
- } });
|
|
|
- })();
|
|
|
- }
|
|
|
-
|
|
|
- if (!('queryKeyCap' in global.KeyboardEvent)) global.KeyboardEvent.queryKeyCap = queryKeyCap;
|
|
|
-
|
|
|
- // Helper for IE8-
|
|
|
- global.identifyKey = function (event) {
|
|
|
- if ('code' in event) return;
|
|
|
-
|
|
|
- var keyInfo = keyInfoForEvent(event);
|
|
|
- event.code = keyInfo ? keyInfo.code : '';
|
|
|
- event.key = keyInfo && 'key' in keyInfo ? keyInfo.key : 'Unidentified';
|
|
|
- event.location = 'location' in event ? event.location : 'keyLocation' in event ? event.keyLocation : keyInfo && 'location' in keyInfo ? keyInfo.location : STANDARD;
|
|
|
- event.locale = '';
|
|
|
- };
|
|
|
-})(window);
|
|
|
-
|
|
|
-},{}],5:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-var EPS = 0.1;
|
|
|
-
|
|
|
-module.exports = AFRAME.registerComponent('checkpoint-controls', {
|
|
|
- schema: {
|
|
|
- enabled: { default: true },
|
|
|
- mode: { default: 'teleport', oneOf: ['teleport', 'animate'] },
|
|
|
- animateSpeed: { default: 3.0 }
|
|
|
- },
|
|
|
-
|
|
|
- init: function init() {
|
|
|
- this.active = true;
|
|
|
- this.checkpoint = null;
|
|
|
-
|
|
|
- this.isNavMeshConstrained = false;
|
|
|
-
|
|
|
- this.offset = new THREE.Vector3();
|
|
|
- this.position = new THREE.Vector3();
|
|
|
- this.targetPosition = new THREE.Vector3();
|
|
|
- },
|
|
|
-
|
|
|
- play: function play() {
|
|
|
- this.active = true;
|
|
|
- },
|
|
|
- pause: function pause() {
|
|
|
- this.active = false;
|
|
|
- },
|
|
|
-
|
|
|
- setCheckpoint: function setCheckpoint(checkpoint) {
|
|
|
- var el = this.el;
|
|
|
-
|
|
|
- if (!this.active) return;
|
|
|
- if (this.checkpoint === checkpoint) return;
|
|
|
-
|
|
|
- if (this.checkpoint) {
|
|
|
- el.emit('navigation-end', { checkpoint: this.checkpoint });
|
|
|
- }
|
|
|
-
|
|
|
- this.checkpoint = checkpoint;
|
|
|
- this.sync();
|
|
|
-
|
|
|
- // Ignore new checkpoint if we're already there.
|
|
|
- if (this.position.distanceTo(this.targetPosition) < EPS) {
|
|
|
- this.checkpoint = null;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- el.emit('navigation-start', { checkpoint: checkpoint });
|
|
|
-
|
|
|
- if (this.data.mode === 'teleport') {
|
|
|
- this.el.setAttribute('position', this.targetPosition);
|
|
|
- this.checkpoint = null;
|
|
|
- el.emit('navigation-end', { checkpoint: checkpoint });
|
|
|
- el.components['movement-controls'].updateNavLocation();
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- isVelocityActive: function isVelocityActive() {
|
|
|
- return !!(this.active && this.checkpoint);
|
|
|
- },
|
|
|
-
|
|
|
- getVelocity: function getVelocity() {
|
|
|
- if (!this.active) return;
|
|
|
-
|
|
|
- var data = this.data;
|
|
|
- var offset = this.offset;
|
|
|
- var position = this.position;
|
|
|
- var targetPosition = this.targetPosition;
|
|
|
- var checkpoint = this.checkpoint;
|
|
|
-
|
|
|
- this.sync();
|
|
|
- if (position.distanceTo(targetPosition) < EPS) {
|
|
|
- this.checkpoint = null;
|
|
|
- this.el.emit('navigation-end', { checkpoint: checkpoint });
|
|
|
- return offset.set(0, 0, 0);
|
|
|
- }
|
|
|
- offset.setLength(data.animateSpeed);
|
|
|
- return offset;
|
|
|
- },
|
|
|
-
|
|
|
- sync: function sync() {
|
|
|
- var offset = this.offset;
|
|
|
- var position = this.position;
|
|
|
- var targetPosition = this.targetPosition;
|
|
|
-
|
|
|
- position.copy(this.el.getAttribute('position'));
|
|
|
- targetPosition.copy(this.checkpoint.object3D.getWorldPosition());
|
|
|
- targetPosition.add(this.checkpoint.components.checkpoint.getOffset());
|
|
|
- offset.copy(targetPosition).sub(position);
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-},{}],6:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-/**
|
|
|
- * Gamepad controls for A-Frame.
|
|
|
- *
|
|
|
- * Stripped-down version of: https://github.com/donmccurdy/aframe-gamepad-controls
|
|
|
- *
|
|
|
- * For more information about the Gamepad API, see:
|
|
|
- * https://developer.mozilla.org/en-US/docs/Web/API/Gamepad_API/Using_the_Gamepad_API
|
|
|
- */
|
|
|
-
|
|
|
-var GamepadButton = require('../../lib/GamepadButton'),
|
|
|
- GamepadButtonEvent = require('../../lib/GamepadButtonEvent');
|
|
|
-
|
|
|
-var JOYSTICK_EPS = 0.2;
|
|
|
-
|
|
|
-module.exports = AFRAME.registerComponent('gamepad-controls', {
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Statics
|
|
|
- */
|
|
|
-
|
|
|
- GamepadButton: GamepadButton,
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Schema
|
|
|
- */
|
|
|
-
|
|
|
- schema: {
|
|
|
- // Controller 0-3
|
|
|
- controller: { default: 0, oneOf: [0, 1, 2, 3] },
|
|
|
-
|
|
|
- // Enable/disable features
|
|
|
- enabled: { default: true },
|
|
|
-
|
|
|
- // Debugging
|
|
|
- debug: { default: false },
|
|
|
-
|
|
|
- // Heading element for rotation
|
|
|
- camera: { default: '[camera]', type: 'selector' },
|
|
|
-
|
|
|
- // Rotation sensitivity
|
|
|
- rotationSensitivity: { default: 2.0 }
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Core
|
|
|
- */
|
|
|
-
|
|
|
- /**
|
|
|
- * Called once when component is attached. Generally for initial setup.
|
|
|
- */
|
|
|
- init: function init() {
|
|
|
- var scene = this.el.sceneEl;
|
|
|
- this.prevTime = window.performance.now();
|
|
|
-
|
|
|
- // Button state
|
|
|
- this.buttons = {};
|
|
|
-
|
|
|
- // Rotation
|
|
|
- var rotation = this.el.object3D.rotation;
|
|
|
- this.pitch = new THREE.Object3D();
|
|
|
- this.pitch.rotation.x = THREE.Math.degToRad(rotation.x);
|
|
|
- this.yaw = new THREE.Object3D();
|
|
|
- this.yaw.position.y = 10;
|
|
|
- this.yaw.rotation.y = THREE.Math.degToRad(rotation.y);
|
|
|
- this.yaw.add(this.pitch);
|
|
|
-
|
|
|
- scene.addBehavior(this);
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Called when component is attached and when component data changes.
|
|
|
- * Generally modifies the entity based on the data.
|
|
|
- */
|
|
|
- update: function update() {
|
|
|
- this.tick();
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Called on each iteration of main render loop.
|
|
|
- */
|
|
|
- tick: function tick(t, dt) {
|
|
|
- this.updateButtonState();
|
|
|
- this.updateRotation(dt);
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Called when a component is removed (e.g., via removeAttribute).
|
|
|
- * Generally undoes all modifications to the entity.
|
|
|
- */
|
|
|
- remove: function remove() {},
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Movement
|
|
|
- */
|
|
|
-
|
|
|
- isVelocityActive: function isVelocityActive() {
|
|
|
- if (!this.data.enabled || !this.isConnected()) return false;
|
|
|
-
|
|
|
- var dpad = this.getDpad(),
|
|
|
- joystick0 = this.getJoystick(0),
|
|
|
- inputX = dpad.x || joystick0.x,
|
|
|
- inputY = dpad.y || joystick0.y;
|
|
|
-
|
|
|
- return Math.abs(inputX) > JOYSTICK_EPS || Math.abs(inputY) > JOYSTICK_EPS;
|
|
|
- },
|
|
|
-
|
|
|
- getVelocityDelta: function getVelocityDelta() {
|
|
|
- var dpad = this.getDpad(),
|
|
|
- joystick0 = this.getJoystick(0),
|
|
|
- inputX = dpad.x || joystick0.x,
|
|
|
- inputY = dpad.y || joystick0.y,
|
|
|
- dVelocity = new THREE.Vector3();
|
|
|
-
|
|
|
- if (Math.abs(inputX) > JOYSTICK_EPS) {
|
|
|
- dVelocity.x += inputX;
|
|
|
- }
|
|
|
- if (Math.abs(inputY) > JOYSTICK_EPS) {
|
|
|
- dVelocity.z += inputY;
|
|
|
- }
|
|
|
-
|
|
|
- return dVelocity;
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Rotation
|
|
|
- */
|
|
|
-
|
|
|
- isRotationActive: function isRotationActive() {
|
|
|
- if (!this.data.enabled || !this.isConnected()) return false;
|
|
|
-
|
|
|
- var joystick1 = this.getJoystick(1);
|
|
|
-
|
|
|
- return Math.abs(joystick1.x) > JOYSTICK_EPS || Math.abs(joystick1.y) > JOYSTICK_EPS;
|
|
|
- },
|
|
|
-
|
|
|
- updateRotation: function updateRotation(dt) {
|
|
|
- if (!this.isRotationActive()) return;
|
|
|
-
|
|
|
- var data = this.data;
|
|
|
- var yaw = this.yaw;
|
|
|
- var pitch = this.pitch;
|
|
|
- var lookControls = data.camera.components['look-controls'];
|
|
|
- var hasLookControls = lookControls && lookControls.pitchObject && lookControls.yawObject;
|
|
|
-
|
|
|
- // Sync with look-controls pitch/yaw if available.
|
|
|
- if (hasLookControls) {
|
|
|
- pitch.rotation.copy(lookControls.pitchObject.rotation);
|
|
|
- yaw.rotation.copy(lookControls.yawObject.rotation);
|
|
|
- }
|
|
|
-
|
|
|
- var lookVector = this.getJoystick(1);
|
|
|
-
|
|
|
- if (Math.abs(lookVector.x) <= JOYSTICK_EPS) lookVector.x = 0;
|
|
|
- if (Math.abs(lookVector.y) <= JOYSTICK_EPS) lookVector.y = 0;
|
|
|
-
|
|
|
- lookVector.multiplyScalar(data.rotationSensitivity * dt / 1000);
|
|
|
- yaw.rotation.y -= lookVector.x;
|
|
|
- pitch.rotation.x -= lookVector.y;
|
|
|
- pitch.rotation.x = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, pitch.rotation.x));
|
|
|
- data.camera.object3D.rotation.set(pitch.rotation.x, yaw.rotation.y, 0);
|
|
|
-
|
|
|
- // Sync with look-controls pitch/yaw if available.
|
|
|
- if (hasLookControls) {
|
|
|
- lookControls.pitchObject.rotation.copy(pitch.rotation);
|
|
|
- lookControls.yawObject.rotation.copy(yaw.rotation);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Button events
|
|
|
- */
|
|
|
-
|
|
|
- updateButtonState: function updateButtonState() {
|
|
|
- var gamepad = this.getGamepad();
|
|
|
- if (this.data.enabled && gamepad) {
|
|
|
-
|
|
|
- // Fire DOM events for button state changes.
|
|
|
- for (var i = 0; i < gamepad.buttons.length; i++) {
|
|
|
- if (gamepad.buttons[i].pressed && !this.buttons[i]) {
|
|
|
- this.emit(new GamepadButtonEvent('gamepadbuttondown', i, gamepad.buttons[i]));
|
|
|
- } else if (!gamepad.buttons[i].pressed && this.buttons[i]) {
|
|
|
- this.emit(new GamepadButtonEvent('gamepadbuttonup', i, gamepad.buttons[i]));
|
|
|
- }
|
|
|
- this.buttons[i] = gamepad.buttons[i].pressed;
|
|
|
- }
|
|
|
- } else if (Object.keys(this.buttons)) {
|
|
|
- // Reset state if controls are disabled or controller is lost.
|
|
|
- this.buttons = {};
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- emit: function emit(event) {
|
|
|
- // Emit original event.
|
|
|
- this.el.emit(event.type, event);
|
|
|
-
|
|
|
- // Emit convenience event, identifying button index.
|
|
|
- this.el.emit(event.type + ':' + event.index, new GamepadButtonEvent(event.type, event.index, event));
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Gamepad state
|
|
|
- */
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the Gamepad instance attached to the component. If connected,
|
|
|
- * a proxy-controls component may provide access to Gamepad input from a
|
|
|
- * remote device.
|
|
|
- *
|
|
|
- * @return {Gamepad}
|
|
|
- */
|
|
|
- getGamepad: function getGamepad() {
|
|
|
- var localGamepad = navigator.getGamepads && navigator.getGamepads()[this.data.controller],
|
|
|
- proxyControls = this.el.sceneEl.components['proxy-controls'],
|
|
|
- proxyGamepad = proxyControls && proxyControls.isConnected() && proxyControls.getGamepad(this.data.controller);
|
|
|
- return proxyGamepad || localGamepad;
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the state of the given button.
|
|
|
- * @param {number} index The button (0-N) for which to find state.
|
|
|
- * @return {GamepadButton}
|
|
|
- */
|
|
|
- getButton: function getButton(index) {
|
|
|
- return this.getGamepad().buttons[index];
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns state of the given axis. Axes are labelled 0-N, where 0-1 will
|
|
|
- * represent X/Y on the first joystick, and 2-3 X/Y on the second.
|
|
|
- * @param {number} index The axis (0-N) for which to find state.
|
|
|
- * @return {number} On the interval [-1,1].
|
|
|
- */
|
|
|
- getAxis: function getAxis(index) {
|
|
|
- return this.getGamepad().axes[index];
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the state of the given joystick (0 or 1) as a THREE.Vector2.
|
|
|
- * @param {number} id The joystick (0, 1) for which to find state.
|
|
|
- * @return {THREE.Vector2}
|
|
|
- */
|
|
|
- getJoystick: function getJoystick(index) {
|
|
|
- var gamepad = this.getGamepad();
|
|
|
- switch (index) {
|
|
|
- case 0:
|
|
|
- return new THREE.Vector2(gamepad.axes[0], gamepad.axes[1]);
|
|
|
- case 1:
|
|
|
- return new THREE.Vector2(gamepad.axes[2], gamepad.axes[3]);
|
|
|
- default:
|
|
|
- throw new Error('Unexpected joystick index "%d".', index);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns the state of the dpad as a THREE.Vector2.
|
|
|
- * @return {THREE.Vector2}
|
|
|
- */
|
|
|
- getDpad: function getDpad() {
|
|
|
- var gamepad = this.getGamepad();
|
|
|
- if (!gamepad.buttons[GamepadButton.DPAD_RIGHT]) {
|
|
|
- return new THREE.Vector2();
|
|
|
- }
|
|
|
- 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));
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns true if the gamepad is currently connected to the system.
|
|
|
- * @return {boolean}
|
|
|
- */
|
|
|
- isConnected: function isConnected() {
|
|
|
- var gamepad = this.getGamepad();
|
|
|
- return !!(gamepad && gamepad.connected);
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns a string containing some information about the controller. Result
|
|
|
- * may vary across browsers, for a given controller.
|
|
|
- * @return {string}
|
|
|
- */
|
|
|
- getID: function getID() {
|
|
|
- return this.getGamepad().id;
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-},{"../../lib/GamepadButton":2,"../../lib/GamepadButtonEvent":3}],7:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-require('./checkpoint-controls');
|
|
|
-require('./gamepad-controls');
|
|
|
-require('./keyboard-controls');
|
|
|
-require('./touch-controls');
|
|
|
-require('./movement-controls');
|
|
|
-require('./trackpad-controls');
|
|
|
-
|
|
|
-},{"./checkpoint-controls":5,"./gamepad-controls":6,"./keyboard-controls":8,"./movement-controls":9,"./touch-controls":10,"./trackpad-controls":11}],8:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-require('../../lib/keyboard.polyfill');
|
|
|
-
|
|
|
-var MAX_DELTA = 0.2,
|
|
|
- PROXY_FLAG = '__keyboard-controls-proxy';
|
|
|
-
|
|
|
-var KeyboardEvent = window.KeyboardEvent;
|
|
|
-
|
|
|
-/**
|
|
|
- * Keyboard Controls component.
|
|
|
- *
|
|
|
- * Stripped-down version of: https://github.com/donmccurdy/aframe-keyboard-controls
|
|
|
- *
|
|
|
- * Bind keyboard events to components, or control your entities with the WASD keys.
|
|
|
- *
|
|
|
- * Why use KeyboardEvent.code? "This is set to a string representing the key that was pressed to
|
|
|
- * generate the KeyboardEvent, without taking the current keyboard layout (e.g., QWERTY vs.
|
|
|
- * Dvorak), locale (e.g., English vs. French), or any modifier keys into account. This is useful
|
|
|
- * when you care about which physical key was pressed, rather thanwhich character it corresponds
|
|
|
- * to. For example, if you’re a writing a game, you might want a certain set of keys to move the
|
|
|
- * player in different directions, and that mapping should ideally be independent of keyboard
|
|
|
- * layout. See: https://developers.google.com/web/updates/2016/04/keyboardevent-keys-codes
|
|
|
- *
|
|
|
- * @namespace wasd-controls
|
|
|
- * keys the entity moves and if you release it will stop. Easing simulates friction.
|
|
|
- * to the entity when pressing the keys.
|
|
|
- * @param {bool} [enabled=true] - To completely enable or disable the controls
|
|
|
- */
|
|
|
-module.exports = AFRAME.registerComponent('keyboard-controls', {
|
|
|
- schema: {
|
|
|
- enabled: { default: true },
|
|
|
- debug: { default: false }
|
|
|
- },
|
|
|
-
|
|
|
- init: function init() {
|
|
|
- this.dVelocity = new THREE.Vector3();
|
|
|
- this.localKeys = {};
|
|
|
- this.listeners = {
|
|
|
- keydown: this.onKeyDown.bind(this),
|
|
|
- keyup: this.onKeyUp.bind(this),
|
|
|
- blur: this.onBlur.bind(this)
|
|
|
- };
|
|
|
- this.attachEventListeners();
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Movement
|
|
|
- */
|
|
|
-
|
|
|
- isVelocityActive: function isVelocityActive() {
|
|
|
- return this.data.enabled && !!Object.keys(this.getKeys()).length;
|
|
|
- },
|
|
|
-
|
|
|
- getVelocityDelta: function getVelocityDelta() {
|
|
|
- var data = this.data,
|
|
|
- keys = this.getKeys();
|
|
|
-
|
|
|
- this.dVelocity.set(0, 0, 0);
|
|
|
- if (data.enabled) {
|
|
|
- if (keys.KeyW || keys.ArrowUp) {
|
|
|
- this.dVelocity.z -= 1;
|
|
|
- }
|
|
|
- if (keys.KeyA || keys.ArrowLeft) {
|
|
|
- this.dVelocity.x -= 1;
|
|
|
- }
|
|
|
- if (keys.KeyS || keys.ArrowDown) {
|
|
|
- this.dVelocity.z += 1;
|
|
|
- }
|
|
|
- if (keys.KeyD || keys.ArrowRight) {
|
|
|
- this.dVelocity.x += 1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return this.dVelocity.clone();
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Events
|
|
|
- */
|
|
|
-
|
|
|
- play: function play() {
|
|
|
- this.attachEventListeners();
|
|
|
- },
|
|
|
-
|
|
|
- pause: function pause() {
|
|
|
- this.removeEventListeners();
|
|
|
- },
|
|
|
-
|
|
|
- remove: function remove() {
|
|
|
- this.pause();
|
|
|
- },
|
|
|
-
|
|
|
- attachEventListeners: function attachEventListeners() {
|
|
|
- window.addEventListener('keydown', this.listeners.keydown, false);
|
|
|
- window.addEventListener('keyup', this.listeners.keyup, false);
|
|
|
- window.addEventListener('blur', this.listeners.blur, false);
|
|
|
- },
|
|
|
-
|
|
|
- removeEventListeners: function removeEventListeners() {
|
|
|
- window.removeEventListener('keydown', this.listeners.keydown);
|
|
|
- window.removeEventListener('keyup', this.listeners.keyup);
|
|
|
- window.removeEventListener('blur', this.listeners.blur);
|
|
|
- },
|
|
|
-
|
|
|
- onKeyDown: function onKeyDown(event) {
|
|
|
- if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
|
|
|
- this.localKeys[event.code] = true;
|
|
|
- this.emit(event);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- onKeyUp: function onKeyUp(event) {
|
|
|
- if (AFRAME.utils.shouldCaptureKeyEvent(event)) {
|
|
|
- delete this.localKeys[event.code];
|
|
|
- this.emit(event);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- onBlur: function onBlur() {
|
|
|
- for (var code in this.localKeys) {
|
|
|
- if (this.localKeys.hasOwnProperty(code)) {
|
|
|
- delete this.localKeys[code];
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- emit: function emit(event) {
|
|
|
- // TODO - keydown only initially?
|
|
|
- // TODO - where the f is the spacebar
|
|
|
-
|
|
|
- // Emit original event.
|
|
|
- if (PROXY_FLAG in event) {
|
|
|
- // TODO - Method never triggered.
|
|
|
- this.el.emit(event.type, event);
|
|
|
- }
|
|
|
-
|
|
|
- // Emit convenience event, identifying key.
|
|
|
- this.el.emit(event.type + ':' + event.code, new KeyboardEvent(event.type, event));
|
|
|
- if (this.data.debug) console.log(event.type + ':' + event.code);
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Accessors
|
|
|
- */
|
|
|
-
|
|
|
- isPressed: function isPressed(code) {
|
|
|
- return code in this.getKeys();
|
|
|
- },
|
|
|
-
|
|
|
- getKeys: function getKeys() {
|
|
|
- if (this.isProxied()) {
|
|
|
- return this.el.sceneEl.components['proxy-controls'].getKeyboard();
|
|
|
- }
|
|
|
- return this.localKeys;
|
|
|
- },
|
|
|
-
|
|
|
- isProxied: function isProxied() {
|
|
|
- var proxyControls = this.el.sceneEl.components['proxy-controls'];
|
|
|
- return proxyControls && proxyControls.isConnected();
|
|
|
- }
|
|
|
-
|
|
|
-});
|
|
|
-
|
|
|
-},{"../../lib/keyboard.polyfill":4}],9:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-/**
|
|
|
- * Movement Controls
|
|
|
- *
|
|
|
- * @author Don McCurdy <dm@donmccurdy.com>
|
|
|
- */
|
|
|
-
|
|
|
-var COMPONENT_SUFFIX = '-controls',
|
|
|
- MAX_DELTA = 0.2,
|
|
|
-
|
|
|
-// ms
|
|
|
-EPS = 10e-6;
|
|
|
-
|
|
|
-module.exports = AFRAME.registerComponent('movement-controls', {
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Schema
|
|
|
- */
|
|
|
-
|
|
|
- dependencies: ['rotation'],
|
|
|
-
|
|
|
- schema: {
|
|
|
- enabled: { default: true },
|
|
|
- controls: { default: ['gamepad', 'trackpad', 'keyboard', 'touch'] },
|
|
|
- speed: { default: 0.3, min: 0 },
|
|
|
- fly: { default: false },
|
|
|
- constrainToNavMesh: { default: false },
|
|
|
- camera: { default: '[camera]', type: 'selector' }
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Lifecycle
|
|
|
- */
|
|
|
-
|
|
|
- init: function init() {
|
|
|
- var el = this.el;
|
|
|
-
|
|
|
- this.velocityCtrl = null;
|
|
|
-
|
|
|
- this.velocity = new THREE.Vector3();
|
|
|
- this.heading = new THREE.Quaternion();
|
|
|
-
|
|
|
- // Navigation
|
|
|
- this.navGroup = null;
|
|
|
- this.navNode = null;
|
|
|
-
|
|
|
- if (el.sceneEl.hasLoaded) {
|
|
|
- this.injectControls();
|
|
|
- } else {
|
|
|
- el.sceneEl.addEventListener('loaded', this.injectControls.bind(this));
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- update: function update(prevData) {
|
|
|
- var el = this.el;
|
|
|
- var data = this.data;
|
|
|
- if (el.sceneEl.hasLoaded) {
|
|
|
- this.injectControls();
|
|
|
- }
|
|
|
- if (data.constrainToNavMesh !== prevData.constrainToNavMesh) {
|
|
|
- var nav = el.sceneEl.systems.nav;
|
|
|
- data.constrainToNavMesh ? nav.addAgent(this) : nav.removeAgent(this);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- injectControls: function injectControls() {
|
|
|
- var data = this.data;
|
|
|
- var name;
|
|
|
-
|
|
|
- for (var i = 0; i < data.controls.length; i++) {
|
|
|
- name = data.controls[i] + COMPONENT_SUFFIX;
|
|
|
- if (!this.el.components[name]) {
|
|
|
- this.el.setAttribute(name, '');
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- updateNavLocation: function updateNavLocation() {
|
|
|
- this.navGroup = null;
|
|
|
- this.navNode = null;
|
|
|
- },
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Tick
|
|
|
- */
|
|
|
-
|
|
|
- tick: function () {
|
|
|
- var start = new THREE.Vector3();
|
|
|
- var end = new THREE.Vector3();
|
|
|
- var clampedEnd = new THREE.Vector3();
|
|
|
-
|
|
|
- return function (t, dt) {
|
|
|
- if (!dt) return;
|
|
|
-
|
|
|
- var el = this.el;
|
|
|
- var data = this.data;
|
|
|
-
|
|
|
- if (!data.enabled) return;
|
|
|
-
|
|
|
- this.updateVelocityCtrl();
|
|
|
- var velocityCtrl = this.velocityCtrl;
|
|
|
- var velocity = this.velocity;
|
|
|
-
|
|
|
- if (!velocityCtrl) return;
|
|
|
-
|
|
|
- // Update velocity. If FPS is too low, reset.
|
|
|
- if (dt / 1000 > MAX_DELTA) {
|
|
|
- velocity.set(0, 0, 0);
|
|
|
- } else {
|
|
|
- this.updateVelocity(dt);
|
|
|
- }
|
|
|
-
|
|
|
- if (data.constrainToNavMesh && velocityCtrl.isNavMeshConstrained !== false) {
|
|
|
-
|
|
|
- if (velocity.lengthSq() < EPS) return;
|
|
|
-
|
|
|
- start.copy(el.object3D.position);
|
|
|
- end.copy(velocity).multiplyScalar(dt / 1000).add(start);
|
|
|
-
|
|
|
- var nav = el.sceneEl.systems.nav;
|
|
|
- this.navGroup = this.navGroup === null ? nav.getGroup(start) : this.navGroup;
|
|
|
- this.navNode = this.navNode || nav.getNode(start, this.navGroup);
|
|
|
- this.navNode = nav.clampStep(start, end, this.navGroup, this.navNode, clampedEnd);
|
|
|
- el.object3D.position.copy(clampedEnd);
|
|
|
- } else if (el.hasAttribute('velocity')) {
|
|
|
- el.setAttribute('velocity', velocity);
|
|
|
- } else {
|
|
|
- el.object3D.position.x += velocity.x * dt / 1000;
|
|
|
- el.object3D.position.y += velocity.y * dt / 1000;
|
|
|
- el.object3D.position.z += velocity.z * dt / 1000;
|
|
|
- }
|
|
|
- };
|
|
|
- }(),
|
|
|
-
|
|
|
- /*******************************************************************
|
|
|
- * Movement
|
|
|
- */
|
|
|
-
|
|
|
- updateVelocityCtrl: function updateVelocityCtrl() {
|
|
|
- var data = this.data;
|
|
|
- if (data.enabled) {
|
|
|
- for (var i = 0, l = data.controls.length; i < l; i++) {
|
|
|
- var control = this.el.components[data.controls[i] + COMPONENT_SUFFIX];
|
|
|
- if (control && control.isVelocityActive()) {
|
|
|
- this.velocityCtrl = control;
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- this.velocityCtrl = null;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- updateVelocity: function () {
|
|
|
- var vector2 = new THREE.Vector2();
|
|
|
- // var matrix = new THREE.Matrix4();
|
|
|
- // var matrix2 = new THREE.Matrix4();
|
|
|
- // var position = new THREE.Vector3();
|
|
|
- // var quaternion = new THREE.Quaternion();
|
|
|
- // var scale = new THREE.Vector3();
|
|
|
-
|
|
|
- return function (dt) {
|
|
|
- var dVelocity = void 0;
|
|
|
- var el = this.el;
|
|
|
- var control = this.velocityCtrl;
|
|
|
- var velocity = this.velocity;
|
|
|
- var data = this.data;
|
|
|
-
|
|
|
- if (control) {
|
|
|
- if (control.getVelocityDelta) {
|
|
|
- dVelocity = control.getVelocityDelta(dt);
|
|
|
- } else if (control.getVelocity) {
|
|
|
- velocity.copy(control.getVelocity());
|
|
|
- return;
|
|
|
- } else if (control.getPositionDelta) {
|
|
|
- velocity.copy(control.getPositionDelta(dt).multiplyScalar(1000 / dt));
|
|
|
- return;
|
|
|
- } else {
|
|
|
- throw new Error('Incompatible movement controls: ', control);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (el.hasAttribute('velocity') && !data.constrainToNavMesh) {
|
|
|
- velocity.copy(this.el.getAttribute('velocity'));
|
|
|
- }
|
|
|
-
|
|
|
- if (dVelocity && data.enabled) {
|
|
|
- // TODO: Handle rotated rig.
|
|
|
- var cameraEl = data.camera;
|
|
|
- // matrix.copy(cameraEl.object3D.matrixWorld);
|
|
|
- // matrix2.getInverse(el.object3D.matrixWorld);
|
|
|
- // matrix.multiply(matrix2);
|
|
|
- // matrix.decompose(position, quaternion, scale);
|
|
|
- // dVelocity.applyQuaternion(quaternion);
|
|
|
-
|
|
|
- // Rotate to heading
|
|
|
- dVelocity.applyQuaternion(cameraEl.object3D.quaternion);
|
|
|
-
|
|
|
- var factor = dVelocity.length();
|
|
|
- if (data.fly) {
|
|
|
- velocity.copy(dVelocity);
|
|
|
- velocity.multiplyScalar(this.data.speed * dt);
|
|
|
- } else {
|
|
|
- vector2.set(dVelocity.x, dVelocity.z);
|
|
|
- vector2.setLength(factor * this.data.speed * dt);
|
|
|
- velocity.x = vector2.x;
|
|
|
- velocity.z = vector2.y;
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
- }()
|
|
|
-});
|
|
|
-
|
|
|
-},{}],10:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-/**
|
|
|
- * Touch-to-move-forward controls for mobile.
|
|
|
- */
|
|
|
-
|
|
|
-module.exports = AFRAME.registerComponent('touch-controls', {
|
|
|
- schema: {
|
|
|
- enabled: { default: true }
|
|
|
- },
|
|
|
-
|
|
|
- init: function init() {
|
|
|
- this.dVelocity = new THREE.Vector3();
|
|
|
- this.bindMethods();
|
|
|
- },
|
|
|
-
|
|
|
- play: function play() {
|
|
|
- this.addEventListeners();
|
|
|
- },
|
|
|
-
|
|
|
- pause: function pause() {
|
|
|
- this.removeEventListeners();
|
|
|
- this.dVelocity.set(0, 0, 0);
|
|
|
- },
|
|
|
-
|
|
|
- remove: function remove() {
|
|
|
- this.pause();
|
|
|
- },
|
|
|
-
|
|
|
- addEventListeners: function addEventListeners() {
|
|
|
- var sceneEl = this.el.sceneEl;
|
|
|
- var canvasEl = sceneEl.canvas;
|
|
|
-
|
|
|
- if (!canvasEl) {
|
|
|
- sceneEl.addEventListener('render-target-loaded', this.addEventListeners.bind(this));
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- canvasEl.addEventListener('touchstart', this.onTouchStart);
|
|
|
- canvasEl.addEventListener('touchend', this.onTouchEnd);
|
|
|
- },
|
|
|
-
|
|
|
- removeEventListeners: function removeEventListeners() {
|
|
|
- var canvasEl = this.el.sceneEl && this.el.sceneEl.canvas;
|
|
|
- if (!canvasEl) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- canvasEl.removeEventListener('touchstart', this.onTouchStart);
|
|
|
- canvasEl.removeEventListener('touchend', this.onTouchEnd);
|
|
|
- },
|
|
|
-
|
|
|
- isVelocityActive: function isVelocityActive() {
|
|
|
- return this.data.enabled && this.isMoving;
|
|
|
- },
|
|
|
-
|
|
|
- getVelocityDelta: function getVelocityDelta() {
|
|
|
- this.dVelocity.z = this.isMoving ? -1 : 0;
|
|
|
- return this.dVelocity.clone();
|
|
|
- },
|
|
|
-
|
|
|
- bindMethods: function bindMethods() {
|
|
|
- this.onTouchStart = this.onTouchStart.bind(this);
|
|
|
- this.onTouchEnd = this.onTouchEnd.bind(this);
|
|
|
- },
|
|
|
-
|
|
|
- onTouchStart: function onTouchStart(e) {
|
|
|
- this.isMoving = true;
|
|
|
- e.preventDefault();
|
|
|
- },
|
|
|
-
|
|
|
- onTouchEnd: function onTouchEnd(e) {
|
|
|
- this.isMoving = false;
|
|
|
- e.preventDefault();
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-},{}],11:[function(require,module,exports){
|
|
|
-'use strict';
|
|
|
-
|
|
|
-/**
|
|
|
- * 3dof (Gear VR, Daydream) controls for mobile.
|
|
|
- */
|
|
|
-
|
|
|
-module.exports = AFRAME.registerComponent('trackpad-controls', {
|
|
|
- schema: {
|
|
|
- enabled: { default: true }
|
|
|
- },
|
|
|
-
|
|
|
- init: function init() {
|
|
|
- this.dVelocity = new THREE.Vector3();
|
|
|
- this.zVel = 0;
|
|
|
- this.bindMethods();
|
|
|
- },
|
|
|
-
|
|
|
- play: function play() {
|
|
|
- this.addEventListeners();
|
|
|
- },
|
|
|
-
|
|
|
- pause: function pause() {
|
|
|
- this.removeEventListeners();
|
|
|
- this.dVelocity.set(0, 0, 0);
|
|
|
- },
|
|
|
-
|
|
|
- remove: function remove() {
|
|
|
- this.pause();
|
|
|
- },
|
|
|
-
|
|
|
- addEventListeners: function addEventListeners() {
|
|
|
- var sceneEl = this.el.sceneEl;
|
|
|
-
|
|
|
- sceneEl.addEventListener('axismove', this.onAxisMove);
|
|
|
- sceneEl.addEventListener('trackpadtouchstart', this.onTouchStart);
|
|
|
- sceneEl.addEventListener('trackpadtouchend', this.onTouchEnd);
|
|
|
- },
|
|
|
-
|
|
|
- removeEventListeners: function removeEventListeners() {
|
|
|
- var sceneEl = this.el.sceneEl;
|
|
|
-
|
|
|
- sceneEl.removeEventListener('axismove', this.onAxisMove);
|
|
|
- sceneEl.removeEventListener('trackpadtouchstart', this.onTouchStart);
|
|
|
- sceneEl.removeEventListener('trackpadtouchend', this.onTouchEnd);
|
|
|
- },
|
|
|
-
|
|
|
- isVelocityActive: function isVelocityActive() {
|
|
|
- return this.data.enabled && this.isMoving;
|
|
|
- },
|
|
|
-
|
|
|
- getVelocityDelta: function getVelocityDelta() {
|
|
|
- this.dVelocity.z = this.isMoving ? -this.zVel : 1;
|
|
|
- return this.dVelocity.clone();
|
|
|
- },
|
|
|
-
|
|
|
- bindMethods: function bindMethods() {
|
|
|
- this.onTouchStart = this.onTouchStart.bind(this);
|
|
|
- this.onTouchEnd = this.onTouchEnd.bind(this);
|
|
|
- this.onAxisMove = this.onAxisMove.bind(this);
|
|
|
- },
|
|
|
-
|
|
|
- onTouchStart: function onTouchStart(e) {
|
|
|
- this.isMoving = true;
|
|
|
- e.preventDefault();
|
|
|
- },
|
|
|
-
|
|
|
- onTouchEnd: function onTouchEnd(e) {
|
|
|
- this.isMoving = false;
|
|
|
- e.preventDefault();
|
|
|
- },
|
|
|
-
|
|
|
- onAxisMove: function onAxisMove(e) {
|
|
|
- var axis_data = e.detail.axis;
|
|
|
-
|
|
|
- if (axis_data[1] < 0) {
|
|
|
- this.zVel = 1;
|
|
|
- }
|
|
|
-
|
|
|
- if (axis_data[1] > 0) {
|
|
|
- this.zVel = -1;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-});
|
|
|
-
|
|
|
-},{}]},{},[1]);
|