Created
November 2, 2018 04:19
-
-
Save LDK/62d5ca528dc43357a0ada646571669b3 to your computer and use it in GitHub Desktop.
pg interface
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="errors" style=" | |
background: #c00; | |
color: #fff; | |
display: none; | |
margin: -20px -20px 20px; | |
padding: 20px; | |
white-space: pre-wrap; | |
"></div> | |
<div id="root"></div> | |
<script> | |
window.addEventListener('mousedown', function(e) { | |
document.body.classList.add('mouse-navigation'); | |
document.body.classList.remove('kbd-navigation'); | |
}); | |
window.addEventListener('keydown', function(e) { | |
if (e.keyCode === 9) { | |
document.body.classList.add('kbd-navigation'); | |
document.body.classList.remove('mouse-navigation'); | |
} | |
}); | |
window.addEventListener('click', function(e) { | |
if (e.target.tagName === 'A' && e.target.getAttribute('href') === '#') { | |
e.preventDefault(); | |
} | |
}); | |
window.onerror = function(message, source, line, col, error) { | |
var text = error ? error.stack || error : message + ' (at ' + source + ':' + line + ':' + col + ')'; | |
errors.textContent += text + '\n'; | |
errors.style.display = ''; | |
}; | |
console.error = (function(old) { | |
return function error() { | |
errors.textContent += Array.prototype.slice.call(arguments).join(' ') + '\n'; | |
errors.style.display = ''; | |
old.apply(this, arguments); | |
} | |
})(console.error); | |
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function Cell(props) { | |
return ( | |
<button className="cell" onClick={props.onClick}> | |
{props.indicator} | |
</button> | |
); | |
} | |
function stepFormat(step){ | |
var bar = (Math.floor((step-1) / 16)) + 1; | |
var beat = (Math.floor((step-1) / 4) % 4) + 1; | |
var tick = (1 + (step-1) * 8) % 32; | |
return {bar: bar, beat: beat, tick: tick}; | |
// return bar + "." + beat + "." + tick; | |
} | |
class Channel extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
trackName: props.trackName || 'New Channel', | |
steps: Array(32).fill(null), | |
volume: 0, | |
pan: 0, | |
transpose: 0, | |
attack: 0, | |
peak: 0, | |
decay: 0, | |
sustain: 0, | |
release: 0 | |
}; | |
} | |
handleClick(i) { | |
const steps = this.state.steps.slice(); | |
steps[i] = !steps[i]; | |
this.setState({steps: steps}); | |
} | |
renderCell(i) { | |
var indicator = ''; | |
var loc = stepFormat(i); | |
if (this.state.steps[i]) { indicator = 'X'; } | |
return <Cell bar={loc.bar} beat={loc.beat} tick={loc.tick} value={this.state.steps[i]} indicator={indicator} onClick={() => this.handleClick(i)} />; | |
} | |
render() { | |
return ( | |
<div> | |
<span>{this.state.trackName}</span> | |
<div className="pattern-row"> | |
{this.renderCell(1)} | |
{this.renderCell(2)} | |
{this.renderCell(3)} | |
{this.renderCell(4)} | |
{this.renderCell(5)} | |
{this.renderCell(6)} | |
{this.renderCell(7)} | |
{this.renderCell(8)} | |
{this.renderCell(9)} | |
{this.renderCell(10)} | |
{this.renderCell(11)} | |
{this.renderCell(12)} | |
{this.renderCell(13)} | |
{this.renderCell(14)} | |
{this.renderCell(15)} | |
{this.renderCell(16)} | |
{this.renderCell(17)} | |
{this.renderCell(18)} | |
{this.renderCell(19)} | |
{this.renderCell(20)} | |
{this.renderCell(21)} | |
{this.renderCell(22)} | |
{this.renderCell(23)} | |
{this.renderCell(24)} | |
{this.renderCell(25)} | |
{this.renderCell(26)} | |
{this.renderCell(27)} | |
{this.renderCell(28)} | |
{this.renderCell(29)} | |
{this.renderCell(30)} | |
{this.renderCell(31)} | |
{this.renderCell(32)} | |
</div> | |
</div> | |
); | |
} | |
} | |
class Pattern extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
bpm: 126, | |
swing: .75, | |
bars: 2, | |
title: 'pyGroove Demo Beat', | |
tracks: { | |
"Kick": | |
{ | |
"wav": "808-Kick2.wav", | |
"pan": 0, | |
"amp": { | |
"volume": "1.2", | |
"attack": 333, | |
"decay": 60000, | |
"peak": 0, | |
"sustain": 0, | |
"release": 212 | |
}, | |
"filter": { | |
"filterType": "lpf", | |
"cutoff": 492 | |
} | |
}, | |
}, | |
selectedTrack: 'Kick' | |
}; | |
this.updateBPM = this.updateBPM.bind(this); | |
} | |
updateBPM(event){ | |
this.setState({bpm: event.target.value}); | |
} | |
renderChannel(trackName) { | |
return <Channel trackName={trackName} />; | |
} | |
render() { | |
const selectedStatus = 'Selected Instrument: Kick'; | |
return ( | |
<div> | |
<form onSubmit={this.handleSubmit}> | |
<div className="status"> | |
BPM: <input type="text" value={this.state.bpm} onChange={this.updateBPM} /> | |
</div> | |
{this.renderChannel('Kick')} | |
{this.renderChannel('Closed Hat')} | |
{this.renderChannel('Open Hat')} | |
{this.renderChannel('Snare')} | |
</form> | |
</div> | |
); | |
} | |
} | |
class Note extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = { | |
offset: 0, | |
transpose: 0, | |
pan: 0, | |
volume: 0, | |
bar: props.bar || null, | |
beat: props.beat || null, | |
tick: props.tick || null | |
}; | |
} | |
} | |
class Song extends React.Component { | |
render() { | |
return ( | |
<div className="song"> | |
<div className="song-pattern"> | |
<Pattern /> | |
</div> | |
<div className="song-info"> | |
<div>{/* status */}</div> | |
<ol>{/* TODO */}</ol> | |
</div> | |
</div> | |
); | |
} | |
} | |
class BPMInput extends React.Component { | |
constructor(props) { | |
super(props); | |
this.state = {value: ''}; | |
this.handleChange = this.handleChange.bind(this); | |
this.handleSubmit = this.handleSubmit.bind(this); | |
} | |
handleChange(event) { | |
this.setState({value: event.target.value}); | |
} | |
handleSubmit(event) { | |
alert('A name was submitted: ' + this.state.value); | |
event.preventDefault(); | |
} | |
render() { | |
return ( | |
<form onSubmit={this.handleSubmit}> | |
<label> | |
Name: | |
<input type="text" value={this.state.value} onChange={this.handleChange} /> | |
</label> | |
<input type="submit" value="Submit" /> | |
</form> | |
); | |
} | |
} | |
// ======================================== | |
ReactDOM.render( | |
<Song />, | |
document.getElementById('root') | |
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://unpkg.com/react@16/umd/react.development.js"></script> | |
<script src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
font: 14px "Century Gothic", Futura, sans-serif; | |
margin: 20px; | |
} | |
ol, ul { | |
padding-left: 30px; | |
} | |
.pattern-row:after { | |
clear: both; | |
content: ""; | |
display: table; | |
} | |
.status { | |
margin-bottom: 10px; | |
} | |
.cell { | |
background-color: #eee; | |
border: 1px solid #999; | |
float: left; | |
font-size: 24px; | |
font-weight: bold; | |
line-height: 34px; | |
height: 32px; | |
margin-right: -1px; | |
margin-top: -1px; | |
padding: 0; | |
text-align: center; | |
width: 24px; | |
} | |
.cell:focus { | |
outline: none; | |
} | |
.cell:nth-child(1), | |
.cell:nth-child(5), | |
.cell:nth-child(9), | |
.cell:nth-child(13), | |
.cell:nth-child(17), | |
.cell:nth-child(21), | |
.cell:nth-child(25), | |
.cell:nth-child(29) | |
{ | |
background-color: #ddbaba; | |
} | |
.kbd-navigation .cell:focus { | |
background: #ddd; | |
} | |
.song { | |
display: flex; | |
flex-direction: row; | |
} | |
.song-info { | |
margin-left: 20px; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment