UNPKG

odin

Version:

Node.js Canvas/WebGL Javascript Game Framework

250 lines (187 loc) 7.17 kB
if (typeof(define) !== "function") { var define = require("amdefine")(module); } define([ "odin/base/event_emitter", "odin/base/dom", "odin/base/object_pool", "odin/math/vec2", "odin/core/input/input" ], function(EventEmitter, Dom, ObjectPool, Vec2, Input) { "use strict"; var min = Math.min, max = Math.max, addEvent = Dom.addEvent, removeEvent = Dom.removeEvent; function Handler() { EventEmitter.call(this); this.element = undefined; } EventEmitter.extend(Handler); Handler.prototype.setElement = function(element) { if (this.element) this.removeElement(); this.element = element; addEvent(element, "mousedown mouseup mousemove mouseout mousewheel DOMMouseScroll", handleMouse, Input); addEvent(top, "keydown keyup", handleKeys, Input); addEvent(element, "touchstart touchmove touchend touchcancel", handleTouches, Input); addEvent(window, "devicemotion", handleDevicemotion, Input); }; Handler.prototype.removeElement = function() { if (!this.element) return; var element = this.element; removeEvent(element, "mousedown mouseup mousemove mouseout mousewheel DOMMouseScroll", handleMouse, Input); removeEvent(top, "keydown keyup", handleKeys, Input); removeEvent(element, "touchstart touchmove touchend touchcancel", handleTouches, Input); removeEvent(window, "devicemotion", handleDevicemotion, Input); this.element = undefined; }; function handleDevicemotion(e) { var acc = e.accelerationIncludingGravity, acceleration; if (acc && (acc.x || acc.y || acc.z)) { acceleration = this.acceleration; acceleration.x = acc.x; acceleration.y = acc.y; acceleration.z = acc.z; this.emit("acceleration"); } } function handleTouches(e) { e.preventDefault(); var type = e.type, touches = this.touches, targetTouches = e.targetTouches, changedTouches = e.changedTouches, i, il; if (type === "touchstart") { for (i = 0, il = targetTouches.length; i < il; i++) this.emit("touchstart", touches.start(i, targetTouches[i])); } else if (type === "touchend") { for (i = 0, il = changedTouches.length; i < il; i++) this.emit("touchend", touches.end(i, changedTouches[i])); } else if (type === "touchcancel") { touches.cancel(); this.emit("touchcancel"); } else if (type === "touchmove") { if (this.touchesMoveNeedsUpdate) { for (i = 0, il = changedTouches.length; i < il; i++) this.emit("touchmove", touches.move(i, changedTouches[i])); this.touchesMoveNeedsUpdate = false; } } } var mouseFirst = false, mouseLast = new Vec2, mouseWheel = 0; function handleMouse(e) { e.preventDefault(); var type = e.type, button; if (type === "mousedown") { button = MOUSE_BUTTONS[e.button]; this.buttons.on(button); updateMousePosition(this, e); this.emit("mousedown", button); } else if (type === "mouseup") { button = MOUSE_BUTTONS[e.button]; this.buttons.off(button); updateMousePosition(this, e); this.emit("mouseup", button); } else if (type === "mouseout") { button = MOUSE_BUTTONS[e.button]; this.buttons.off(button); updateMousePosition(this, e); this.emit("mouseout", button); } else if (type === "mousewheel" || type === "DOMMouseScroll") { mouseWheel = max(-1, min(1, (e.wheelDelta || -e.detail))); this.mouseWheel = mouseWheel; this.emit("mousewheel", mouseWheel); } else if (type === "mousemove") { if (this.mouseMoveNeedsUpdate) { updateMousePosition(this, e); this.mouseMoveNeedsUpdate = false; this.emit("mousemove"); } } } function updateMousePosition(input, e) { var position = input.mousePosition, delta = input.mouseDelta, element = e.target || e.srcElement, offsetX = element.offsetLeft || 0, offsetY = element.offsetTop || 0, x = (e.pageX || e.clientX) - offsetX, y = (e.pageY || e.clientY) - offsetY; mouseLast.x = mouseFirst ? position.x : x; mouseLast.y = mouseFirst ? position.y : y; position.x = x; position.y = y; delta.x = position.x - mouseLast.x; delta.y = position.y - mouseLast.y; mouseFirst = true; } function handleKeys(e) { e.preventDefault(); var type = e.type, key = KEY_CODES[e.keyCode]; if (type === "keydown") { this.buttons.on(key); this.emit("keydown", key); } else if (type === "keyup") { this.buttons.off(key); this.emit("keyup", key); } } var MOUSE_BUTTONS = { "0": "mouse0", "1": "mouse1", "2": "mouse2" } var KEY_CODES = { 8: "backspace", 9: "tab", 13: "enter", 16: "shift", 17: "ctrl", 18: "alt", 19: "pause", 20: "capslock", 27: "escape", 32: "space", 33: "pageup", 34: "pagedown", 35: "end", 37: "left", 38: "up", 39: "right", 40: "down", 45: "insert", 46: "delete", 112: "f1", 113: "f2", 114: "f3", 115: "f4", 116: "f5", 117: "f6", 118: "f7", 119: "f8", 120: "f9", 121: "f10", 122: "f11", 123: "f12", 144: "numlock", 145: "scrolllock", 186: "semicolon", 187: "equal", 188: "comma", 189: "dash", 190: "period", 191: "slash", 192: "graveaccent", 219: "openbracket", 220: "backslash", 221: "closebraket", 222: "singlequote" }; for (var i = 48; i <= 90; i++) KEY_CODES[i] = String.fromCharCode(i).toLowerCase(); return new Handler; } );