/*globals React, App */ (function () { 'use strict'; /** * Display keyboard */ App.components.create('Key', { displayName: 'Board', mixins: [React.addons.PureRenderMixin], clicked: false, statics: { offset: 27 + App.MIDI.keyOffset, keysToNotes: [ 65, 50, 90, 51, 69, 82, 53, 84, 54, 89, 55, 85, 73, 57, 79, 48, 80, 87, 83, 88, 68, 67, 70, 86, 66, 72, 78, 74, 188, 190, 76, 191, 77, 223, 192, 16 ] }, /** * Set given note on given channel * * @param {note: number} Note number * @param {channel: number} Channel ID * @param {velocity: number} Note velocity */ on: function (note, channel, velocity) { var key = this.refs['key-' + note]; if (key) { key.on(channel, velocity); } }, /** * Check whether given note plays on given channel * * @param {note: number} Note number * @param {channel: number} Channel ID */ isOn: function (note, channel) { var key = this.refs['key-' + note]; return (key.state.channels.indexOf(channel) > -1); }, /** * Set given note off given channel * * @param {note: number} Note number * @param {channel: number} Channel ID */ off: function (note, channel) { var key = this.refs['key-' + note]; if (key) { key.off(channel); } }, /** * Set all notes off */ allOff: function () { var i, keys = this.refs; for (i in keys) { if (keys.hasOwnProperty(i) && i.substr(0, 4) === 'key-') { keys[i].off(); } } }, /** * Events */ componentDidMount: function () { window.addEventListener('keydown', this.keyDown); window.addEventListener('keyup', this.keyUp); window.addEventListener('mouseup', this.release); }, componentWillUnmount: function () { window.removeEventListener('keydown', this.keyDown); window.removeEventListener('keyup', this.keyUp); window.removeEventListener('mouseup', this.release); }, /* mouse click */ click: function (e) { if (e.button !== 0) { return; } this.clicked = true; }, /* mouse release */ release: function () { this.clicked = false; }, /* play keys with keyboard (the real one) */ keyDown: function (e) { var code = e.keyCode, index, Keyboard = App.components.Key.Board; // play note if ((index = Keyboard.keysToNotes.indexOf(code)) > -1) { index += Keyboard.offset; if (!this.isOn(index, -1)) { this.on(index, -1, 127); } e.preventDefault(); } }, /* release keys */ keyUp: function (e) { var index, Keyboard = App.components.Key.Board; if ((index = Keyboard.keysToNotes.indexOf(e.keyCode)) > -1) { this.off(index + Keyboard.offset, -1); e.preventDefault(); } }, /** * Whether keys should be played on mouse over */ canPlay: function () { return this.clicked; }, /** * Render keyboard */ render: function () { var i, offset = App.MIDI.keyOffset, length = 88 + offset, keys = []; for (i = offset; i < length; i += 1) { keys.push(App.components.Key.Key({ key: i, ref: 'key-' + i, note: i, canPlay: this.canPlay })); } return React.DOM.p({ className: 'keyboard', onMouseDown: this.click }, keys); } }); }());