1 /** 2 * Copyright (C) 2009-2012 Klaus Reimer <k@ailis.de> 3 * See LICENSE.txt for licensing information 4 * 5 * @require threedee.js 6 * @require threedee/updater/NodeUpdater.js 7 */ 8 9 /** 10 * Constructs a new keyboard updater connected to the specified HTML element. 11 * 12 * @param {(Window|Element)=} element 13 * The element to which the keyboard event handlers are connected. 14 * This is optional and defaults to the browser window. 15 * 16 * @constructor 17 * @extends {threedee.NodeUpdater} 18 * @class 19 * This updater can be bound to a HTML element (Window is default) where 20 * it listens for key presses and releases to transform the connected node 21 * according to the key pressed and velocity settings. 22 */ 23 24 threedee.KeyboardUpdater = function(element) 25 { 26 var updater; 27 28 threedee.NodeUpdater.call(this); 29 if (!element) element = window; 30 this.element = element; 31 32 updater = this; 33 34 element.addEventListener("keydown", this.handleKeyDown.bind(this), false); 35 element.addEventListener("keyup", this.handleKeyUp.bind(this), false); 36 }; 37 threedee.inherit(threedee.KeyboardUpdater, threedee.NodeUpdater); 38 39 /** 40 * The element to which the keyboard event handlers are connected. 41 * @private 42 * @type {!(Window|Element)} 43 */ 44 threedee.KeyboardUpdater.prototype.element; 45 46 /** 47 * The movement speed in units per second. 48 * @private 49 * @type {number} 50 */ 51 threedee.KeyboardUpdater.prototype.speed = 10; 52 53 /** 54 * The rotation speed in clock-wise RAD per second. 55 * @private 56 * @type {number} 57 */ 58 threedee.KeyboardUpdater.prototype.rotSpeed = 45 * Math.PI / 180; 59 60 /** 61 * Flag indicating if the left key has been pressed. 62 * @private 63 * @type {boolean} 64 */ 65 threedee.KeyboardUpdater.prototype.left = false; 66 67 /** 68 * Flag indicating if the right key has been pressed. 69 * @private 70 * @type {boolean} 71 */ 72 threedee.KeyboardUpdater.prototype.right = false; 73 74 /** 75 * Flag indicating if the up key has been pressed. 76 * @private 77 * @type {boolean} 78 */ 79 threedee.KeyboardUpdater.prototype.up = false; 80 81 /** 82 * Flag indicating if the down key has been pressed. 83 * @private 84 * @type {boolean} 85 */ 86 threedee.KeyboardUpdater.prototype.down = false; 87 88 /** 89 * Flag indicating if the forward key has been pressed. 90 * @private 91 * @type {boolean} 92 */ 93 threedee.KeyboardUpdater.prototype.forward = false; 94 95 /** 96 * Flag indicating if the backward key has been pressed. 97 * @private 98 * @type {boolean} 99 */ 100 threedee.KeyboardUpdater.prototype.backward = false; 101 102 /** 103 * Flag indicating if the pitch up key has been pressed. 104 * @private 105 * @type {boolean} 106 */ 107 threedee.KeyboardUpdater.prototype.pitchUp = false; 108 109 /** 110 * Flag indicating if the pitch down key has been pressed. 111 * @private 112 * @type {boolean} 113 */ 114 threedee.KeyboardUpdater.prototype.pitchDown = false; 115 116 /** 117 * Flag indicating if the yaw left key has been pressed. 118 * @private 119 * @type {boolean} 120 */ 121 threedee.KeyboardUpdater.prototype.yawLeft = false; 122 123 /** 124 * Flag indicating if the yaw right key has been pressed. 125 * @private 126 * @type {boolean} 127 */ 128 threedee.KeyboardUpdater.prototype.yawRight = false; 129 130 /** 131 * Flag indicating if the roll left key has been pressed. 132 * @private 133 * @type {boolean} 134 */ 135 threedee.KeyboardUpdater.prototype.rollLeft = false; 136 137 /** 138 * Flag indicating if the roll right key has been pressed. 139 * @private 140 * @type {boolean} 141 */ 142 threedee.KeyboardUpdater.prototype.rollRight = false; 143 144 /** 145 * Handles the key-down event. 146 * 147 * @param {!Event} e 148 * The event. 149 * @private 150 */ 151 threedee.KeyboardUpdater.prototype.handleKeyDown = function(e) 152 { 153 switch (e.keyCode) 154 { 155 case 87: 156 this.forward = true; 157 break; 158 159 case 83: 160 this.backward = true; 161 break; 162 163 case 65: 164 this.left = true; 165 break; 166 167 case 68: 168 this.right = true; 169 break; 170 171 case 82: 172 this.down = true; 173 break; 174 175 case 70: 176 this.up = true; 177 break; 178 179 case 37: 180 this.yawLeft = true; 181 break; 182 183 case 39: 184 this.yawRight = true; 185 break; 186 187 case 38: 188 this.pitchUp = true; 189 break; 190 191 case 40: 192 this.pitchDown = true; 193 break; 194 195 case 81: 196 this.rollLeft = true; 197 break; 198 199 case 69: 200 this.rollRight = true; 201 break; 202 203 default: 204 return; 205 } 206 e.preventDefault(); 207 }; 208 209 /** 210 * Handles the key-up event. 211 * 212 * @param {!Event} e 213 * The event. 214 * @private 215 */ 216 threedee.KeyboardUpdater.prototype.handleKeyUp = function(e) 217 { 218 switch (e.keyCode) 219 { 220 case 87: 221 this.forward = false; 222 break; 223 224 case 83: 225 this.backward = false; 226 break; 227 228 case 65: 229 this.left = false; 230 break; 231 232 case 68: 233 this.right = false; 234 break; 235 236 case 82: 237 this.down = false; 238 break; 239 240 case 70: 241 this.up = false; 242 break; 243 244 case 37: 245 this.yawLeft = false; 246 break; 247 248 case 39: 249 this.yawRight = false; 250 break; 251 252 case 38: 253 this.pitchUp = false; 254 break; 255 256 case 40: 257 this.pitchDown = false; 258 break; 259 260 case 81: 261 this.rollLeft = false; 262 break; 263 264 case 69: 265 this.rollRight = false; 266 break; 267 268 default: 269 } 270 e.preventDefault(); 271 }; 272 273 /** 274 * @inheritDoc 275 * 276 * @param {!threedee.SceneNode} node 277 * @param {number} delta 278 */ 279 threedee.KeyboardUpdater.prototype.update = function(node, delta) 280 { 281 var x, y, z, rx, ry, rz, transform; 282 283 x = this.right ? 1 : (this.left ? -1 : 0); 284 y = this.down ? 1 : (this.up ? -1 : 0); 285 z = this.forward ? 1 : (this.backward ? -1 : 0); 286 rx = this.pitchUp ? 1 : (this.pitchDown ? -1 : 0); 287 ry = this.yawRight ? 1 : (this.yawLeft ? -1 : 0); 288 rz = this.rollLeft ? 1 : (this.rollRight ? -1 : 0); 289 290 transform = node.getTransform(); 291 292 transform.translate(x * this.speed * delta / 1000, y * this.speed 293 * delta / 1000, z * this.speed * delta / 1000); 294 295 transform.rotateX(rx * this.rotSpeed * delta / 1000); 296 transform.rotateY(ry * this.rotSpeed * delta / 1000); 297 transform.rotateZ(rz * this.rotSpeed * delta / 1000); 298 }; 299