const specialKeyMap = { backspace: 8, tab: 9, enter: 13, shift: 16, ctrl: 17, alt: 18, pausebreak: 19, capslock: 20, escape: 27, pgup: 33, pgdown: 34, end: 35, home: 36, left: 37, up: 38, right: 39, down: 40, insert: 45, delete: 46, 'left-window': 91, 'right-window': 92, select: 93, numpad0: 96, numpad1: 97, numpad2: 98, numpad3: 99, numpad4: 100, numpad5: 101, numpad6: 102, numpad7: 103, numpad8: 104, numpad9: 105, multiply: 106, add: 107, subtract: 109, decimal: 110, divide: 111, f1: 112, f2: 113, f3: 114, f4: 115, f5: 116, f6: 117, f7: 118, f8: 119, f9: 120, f10: 121, f11: 122, f12: 123, numlock: 144, scrolllock: 145, 'semi-colon': 186, equals: 187, comma: 188, dash: 189, period: 190, fwdslash: 191, grave: 192, 'open-bracket': 219, bkslash: 220, 'close-braket': 221, 'single-quote': 222 } class Input { constructor (canvas) { this.keyList = {} this.previousKeyList = {} this.canvas = canvas this.mouse = { pos: { x: 0, y: 0 }, frame: { x: 0, y: 0 }, previous: { x: 0, y: 0 } } window.addEventListener('keydown', (e) => this.keyDown(e), false) window.addEventListener('keyup', (e) => this.keyUp(e), false) canvas.addEventListener('mousemove', (e) => { let x let y if (e.changedTouches) { const touch = e.changedTouches[0] if (touch) { e.pageX = touch.pageX e.pageY = touch.pageY } } if (e.pageX || e.pageY) { x = e.pageX y = e.pageY } else { x = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft y = e.clientY + document.body.scrollTop + document.documentElement.scrollTop } x -= canvas.offsetLeft y -= canvas.offsetTop this.mouse.frame.x = x this.mouse.frame.y = y }, false) canvas.addEventListener('mousedown', (e) => { e.preventDefault() this.mouse['btn' + e.button] = true }) canvas.addEventListener('mouseup', (e) => { e.preventDefault() this.mouse['btn' + e.button] = false }) canvas.addEventListener('contextmenu', (e) => { e.preventDefault() }) } get mousePos () { return this.mouse.pos } get mouseMoved () { return (this.mouse.pos.x !== this.mouse.previous.x || this.mouse.pos.y !== this.mouse.previous.y) } get mouseOffset () { return { x: this.mouse.previous.x - this.mouse.pos.x, y: this.mouse.previous.y - this.mouse.pos.y } } toggleKey (keyCode, on) { // Find key in special key list let key = null for (const k in specialKeyMap) { const val = specialKeyMap[k] if (keyCode === val) { key = k break } } // Use fromCharCode if (!key) { key = String.fromCharCode(keyCode).toLowerCase() } this.keyList[key] = (on === true) } keyDown (e) { let keycode if (window.event) { keycode = window.event.keyCode } else if (e) { keycode = e.which } this.toggleKey(keycode, true) } keyUp (e) { let keycode if (window.event) { keycode = window.event.keyCode } else if (e) { keycode = e.which } this.toggleKey(keycode, false) } down (key) { return this.keyList[key] != null ? this.keyList[key] : false } downLast (key) { return this.previousKeyList[key] != null ? this.previousKeyList[key] : false } isDown (key) { return this.down(key) && this.downLast(key) } isUp (key) { return !this.isDown(key) } isPressed (key) { return this.down(key) === true && this.downLast(key) === false } update () { this.previousKeyList = {} for (const k in this.keyList) { if (this.keyList[k] === true) { this.previousKeyList[k] = true } } // Mouse positions in the previous frame this.mouse.previous.x = this.mouse.pos.x this.mouse.previous.y = this.mouse.pos.y // Mouse positions in the current frame // Convert to OpenGL coordinate system this.mouse.pos.x = this.mouse.frame.x / this.canvas.width * 2 - 1 this.mouse.pos.y = this.mouse.frame.y / this.canvas.height * 2 - 1 } } export default Input