├── .eslintignore
├── .gitignore
├── .babelrc
├── assets
├── images
│ └── dark-wood.png
├── js
│ ├── samples.js
│ ├── position.js
│ ├── demo_track.js
│ ├── null_track.js
│ └── patterns.js
└── style
│ └── style.css
├── dist
├── assets
│ └── samples
│ │ ├── Clap.wav
│ │ ├── Clave.wav
│ │ ├── Kick.wav
│ │ ├── Snare.wav
│ │ ├── HighTom.wav
│ │ ├── LowTom.wav
│ │ ├── OpenHat.wav
│ │ └── ClosedHat.wav
├── e3577ddd019c610cedbeb38ebff4e2ef.png
├── index.html
├── manifest.9b0443ed5b4bcfffb491.js
├── style.css
└── bundle.be9505c48da7088d1b85.js
├── src
├── components
│ ├── assets
│ │ └── samples
│ │ │ ├── Clap.wav
│ │ │ ├── Clave.wav
│ │ │ ├── Kick.wav
│ │ │ ├── Snare.wav
│ │ │ ├── HighTom.wav
│ │ │ ├── LowTom.wav
│ │ │ ├── OpenHat.wav
│ │ │ └── ClosedHat.wav
│ ├── screws.js
│ ├── progress_bar.js
│ ├── channel_row.js
│ ├── playbar.js
│ ├── toggle.js
│ ├── knob.js
│ └── drum_machine.js
└── index.js
├── .eslintrc.json
├── index.html
├── README.md
├── package.json
└── webpack.config.js
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | .DS_STORE
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["babel-preset-env", "react"]
3 | }
4 |
--------------------------------------------------------------------------------
/assets/images/dark-wood.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/assets/images/dark-wood.png
--------------------------------------------------------------------------------
/dist/assets/samples/Clap.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/Clap.wav
--------------------------------------------------------------------------------
/dist/assets/samples/Clave.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/Clave.wav
--------------------------------------------------------------------------------
/dist/assets/samples/Kick.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/Kick.wav
--------------------------------------------------------------------------------
/dist/assets/samples/Snare.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/Snare.wav
--------------------------------------------------------------------------------
/dist/assets/samples/HighTom.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/HighTom.wav
--------------------------------------------------------------------------------
/dist/assets/samples/LowTom.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/LowTom.wav
--------------------------------------------------------------------------------
/dist/assets/samples/OpenHat.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/OpenHat.wav
--------------------------------------------------------------------------------
/dist/assets/samples/ClosedHat.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/assets/samples/ClosedHat.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/Clap.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/Clap.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/Clave.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/Clave.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/Kick.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/Kick.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/Snare.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/Snare.wav
--------------------------------------------------------------------------------
/dist/e3577ddd019c610cedbeb38ebff4e2ef.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/dist/e3577ddd019c610cedbeb38ebff4e2ef.png
--------------------------------------------------------------------------------
/src/components/assets/samples/HighTom.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/HighTom.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/LowTom.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/LowTom.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/OpenHat.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/OpenHat.wav
--------------------------------------------------------------------------------
/src/components/assets/samples/ClosedHat.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kirie/StepSequencer/HEAD/src/components/assets/samples/ClosedHat.wav
--------------------------------------------------------------------------------
/src/components/screws.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 |
3 | export default () =>
;
4 |
--------------------------------------------------------------------------------
/assets/js/samples.js:
--------------------------------------------------------------------------------
1 | export default [
2 | "../assets/samples/BD.WAV",
3 | "../assets/samples/SD.WAV",
4 | "../assets/samples/CH.WAV",
5 | "../assets/samples/CP.WAV",
6 | "../assets/samples/CB.WAV",
7 | "../assets/samples/CL.wav",
8 | "../assets/samples/HC.wav",
9 | "../assets/samples/LC.wav"
10 | ];
11 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import DrumMachine from './components/drum_machine';
4 | import '../assets/style/style.css';
5 |
6 | const App = () => {
7 | return (
8 |
9 | );
10 | };
11 |
12 | ReactDOM.render(, document.getElementById('root'));
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "airbnb",
3 | "installedESLint": true,
4 | "plugins": [
5 | "react",
6 | "jsx-a11y",
7 | "import"
8 | ],
9 | "rules": {
10 | "brace-style": [2, "stroustrup", {"allowSingleLine": false}],
11 | "comma-dangle": [2, "never"],
12 | "react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }]
13 | }
14 | }
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | SEQUENCE
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/progress_bar.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const progressBar = (props) => {
4 | const temp = Array(16).fill(1);
5 | const temp2 = temp.map((v, i) => {
6 | if (i === props.prog) {
7 | return ();
11 | }
12 | return ();
13 | });
14 | return (
15 | {temp2}
16 | );
17 | };
18 |
19 | progressBar.propTypes = {
20 | prog: PropTypes.number.isRequired
21 | };
22 |
23 |
24 | export default progressBar;
25 |
--------------------------------------------------------------------------------
/assets/js/position.js:
--------------------------------------------------------------------------------
1 | export default {
2 | '0:0:0': 0,
3 | '0:0:1': 1,
4 | '0:0:2': 2,
5 | '0:0:3': 3,
6 | '0:1:0': 4,
7 | '0:1:1': 5,
8 | '0:1:2': 6,
9 | '0:1:3': 7,
10 | '0:2:0': 8,
11 | '0:2:1': 9,
12 | '0:2:2': 10,
13 | '0:2:3': 11,
14 | '0:3:0': 12,
15 | '0:3:1': 13,
16 | '0:3:2': 14,
17 | '0:3:3': 15,
18 | '1:0:0': 0,
19 | '1:0:1': 1,
20 | '1:0:2': 2,
21 | '1:0:3': 3,
22 | '1:1:0': 4,
23 | '1:1:1': 5,
24 | '1:1:2': 6,
25 | '1:1:3': 7,
26 | '1:2:0': 8,
27 | '1:2:1': 9,
28 | '1:2:2': 10,
29 | '1:2:3': 11,
30 | '1:3:0': 12,
31 | '1:3:1': 13,
32 | '1:3:2': 14,
33 | '1:3:3': 15
34 | };
35 |
--------------------------------------------------------------------------------
/dist/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | SEQUENCE
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/components/channel_row.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 |
3 | const channelRow = (props) => {
4 | function makeRow(v, i) {
5 | const channelClasses = v ? 'lighton' : 'lightoff';
6 | return (
7 |
14 | );
15 | }
16 |
17 | return (
18 |
19 | {props.channel.map(makeRow, this)}
20 |
21 | );
22 | };
23 |
24 | channelRow.propTypes = {
25 | channelNum: PropTypes.number.isRequired,
26 | bside: PropTypes.bool.isRequired,
27 | updateSeq: PropTypes.func.isRequired,
28 | channel: PropTypes.array.isRequired
29 | };
30 |
31 | export default channelRow;
32 |
--------------------------------------------------------------------------------
/src/components/playbar.js:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react';
2 | import Toggle from './toggle';
3 |
4 | const playBar = (props) => {
5 | return (
6 |
7 |
SEQUENCE
8 |
9 |
10 |
11 |
12 |
17 |
18 | );
19 | };
20 |
21 | playBar.propTypes = {
22 | bpm_num: PropTypes.number.isRequired,
23 | toggle_f: PropTypes.func.isRequired,
24 | tempo_f: PropTypes.func.isRequired,
25 | playbutton_f: PropTypes.func.isRequired
26 | };
27 |
28 | export default playBar;
29 |
--------------------------------------------------------------------------------
/src/components/toggle.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 |
3 | class Toggle extends Component {
4 | constructor(props) {
5 | super(props);
6 | this.state = {
7 | toggled: false
8 | };
9 | this.handleChange = this.handleChange.bind(this);
10 | }
11 |
12 | handleChange() {
13 | this.props.abfunc();
14 | this.setState({ toggled: !this.state.toggled });
15 | }
16 |
17 | render() {
18 | let toggleClasses = 'togglebox';
19 | if (this.state.toggled) {
20 | toggleClasses += ' toggled';
21 | }
22 |
23 | return (
24 |
28 |
A
29 |
32 |
B
33 |
34 |
35 | );
36 | }
37 | }
38 |
39 | Toggle.propTypes = {
40 | abfunc: PropTypes.func.isRequired
41 | };
42 |
43 | export default Toggle;
44 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # StepSequencer
2 |
3 | [Demo](https://kirie.github.io/StepSequencer)
4 |
5 | A simple TR-808 inspired drum step sequencer using React and Tone.js. Each of the eight horizontal rows represents a single sample sound with 16 steps of 16th notes(4/4 time) per side. The sequencer pattern spans a total of 32 steps or 2 bar measures. The A/B switch toggles the 2nd set of 16th notes. The rows are unlabeled.
6 |
7 | The preset pattern is from this 808 [song](https://www.youtube.com/watch?v=rjlSiASsUIs)
8 |
9 | ### Motivation
10 |
11 | Create something interesting using Web Audio and to test the new codesplitting with Webpack 2.
12 |
13 |
14 | ### Features
15 |
16 | * Codesplit bundles using Webpack 2(bundle.js and vendor.js)
17 | * A/B side pattern switch
18 | * Classic TR-808 colours
19 | * Master 2-bus fader(WIP)
20 |
21 |
22 | ### Installing dev
23 |
24 | ```
25 | npm install
26 | npm run servedev
27 | ```
28 |
29 |
30 | ## Built With
31 |
32 | * [React](https://github.com/facebook/react)
33 | * [Tone.js](https://tonejs.github.io)
34 |
35 |
36 | ## Author
37 |
38 | * [kirie](https://github.com/kirie)
39 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "stepsequencer",
3 | "version": "1.0.0",
4 | "description": "Step Sequencer",
5 | "main": "index.js",
6 | "scripts": {
7 | "clean": "rimraf dist",
8 | "servedev": "webpack-dev-server",
9 | "build": "NODE_ENV=production npm run clean && webpack",
10 | "deployghpages": "npm run build && git subtree push --prefix dist origin gh-pages"
11 | },
12 | "repository": {
13 | "type": "git",
14 | "url": "git+https://github.com/kirie/StepSequencer.git"
15 | },
16 | "author": "kirie",
17 | "license": "ISC",
18 | "bugs": {
19 | "url": "https://github.com/kirie/StepSequencer/issues"
20 | },
21 | "homepage": "https://github.com/kirie/StepSequencer#readme",
22 | "dependencies": {
23 | "react": "^15.4.2",
24 | "react-dom": "^15.4.2",
25 | "tone": "^0.9.0"
26 | },
27 | "devDependencies": {
28 | "babel-core": "^6.21.0",
29 | "babel-loader": "^6.2.10",
30 | "babel-preset-env": "^1.1.8",
31 | "babel-preset-react": "^6.16.0",
32 | "copy-webpack-plugin": "^4.0.1",
33 | "css-loader": "^0.26.1",
34 | "eslint": "^3.13.1",
35 | "eslint-config-airbnb": "^14.0.0",
36 | "eslint-plugin-import": "^2.2.0",
37 | "eslint-plugin-jsx-a11y": "^3.0.2",
38 | "eslint-plugin-react": "^6.9.0",
39 | "extract-text-webpack-plugin": "^2.0.0-beta.4",
40 | "file-loader": "^0.9.0",
41 | "html-webpack-plugin": "^2.26.0",
42 | "image-webpack-loader": "^3.1.0",
43 | "rimraf": "^2.5.4",
44 | "style-loader": "^0.13.1",
45 | "url-loader": "^0.5.7",
46 | "webpack": "^2.2.0-rc.0",
47 | "webpack-dev-server": "^1.16.2"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const path = require('path');
2 | const webpack = require('webpack');
3 | const ExtractTextPlugin = require('extract-text-webpack-plugin');
4 | const HtmlWebpackPlugin = require('html-webpack-plugin');
5 | const CopyWebpackPlugin = require('copy-webpack-plugin');
6 |
7 | const VENDOR_LIBS = ['react', 'tone', 'react-dom'];
8 |
9 | module.exports = {
10 | entry: {
11 | bundle: './src/index.js',
12 | vendor: VENDOR_LIBS
13 | },
14 | output: {
15 | path: path.join(__dirname, 'dist'),
16 | filename: '[name].[chunkhash].js'
17 | },
18 | module: {
19 | rules: [
20 | {
21 | use: 'babel-loader',
22 | test: /\.js$/,
23 | exclude: /node_modules/
24 | },
25 | {
26 | loader: ExtractTextPlugin.extract({
27 | loader: 'css-loader'
28 | }),
29 | test: /\.css$/
30 | },
31 | {
32 | test: /\.(jpe?g|png|gif|svg)$/,
33 | use: [
34 | {
35 | loader: 'url-loader',
36 | options: { limit: 40000 }
37 | },
38 | 'image-webpack-loader'
39 | ]
40 | },
41 | {
42 | test: /\.wav$/,
43 | use: 'file-loader'
44 | }
45 | ]
46 | },
47 | plugins: [
48 | new ExtractTextPlugin('style.css'),
49 | new webpack.optimize.CommonsChunkPlugin({
50 | names: ['vendor', 'manifest']
51 | }),
52 | new HtmlWebpackPlugin({
53 | template: 'index.html'
54 | }),
55 | new webpack.DefinePlugin({
56 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
57 | }),
58 | new CopyWebpackPlugin([
59 | { from: 'src/components/assets/samples/', to: 'assets/samples/' }
60 | ])
61 | ]
62 | };
63 |
--------------------------------------------------------------------------------
/assets/js/demo_track.js:
--------------------------------------------------------------------------------
1 | export const demoTrack = [
2 | [
3 | true, null, null, null, null, null, null, true,
4 | true, null, true, null, true, null, null, true,
5 | true, null, null, null, null, null, null, null,
6 | true, null, null, null, null, null, null, true
7 | ],
8 | [
9 | null, null, null, null, null, null, null, null,
10 | null, null, true, true, null, null, null, null,
11 | null, null, null, null, null, null, true, true,
12 | null, true, null, true, null, true, null, null
13 | ],
14 | [
15 | null, null, null, null, true, null, null, null,
16 | null, null, null, null, null, null, null, null,
17 | null, null, null, null, true, null, null, null,
18 | null, null, null, null, null, null, null, null
19 | ],
20 | [
21 | true, null, null, true, null, null, true, null,
22 | null, null, null, null, null, null, null, null,
23 | true, null, null, true, null, null, true, null,
24 | null, null, true, null, null, true, null, null
25 | ],
26 | [
27 | null, null, null, null, null, null, null, null,
28 | null, null, null, null, null, null, null, null,
29 | null, null, null, null, null, null, null, null,
30 | null, null, null, null, true, null, true, null
31 | ],
32 | [
33 | true, null, true, true, true, null, true, null,
34 | true, null, true, null, true, null, true, true,
35 | true, null, true, null, true, null, true, null,
36 | true, true, true, null, true, null, true, true
37 | ],
38 | [
39 | null, null, null, null, null, null, true, null,
40 | null, null, null, null, null, null, null, null,
41 | null, null, true, null, null, null, true, null,
42 | null, null, true, null, null, true, null, null
43 | ],
44 | [
45 | null, null, true, null, null, null, null, null,
46 | null, null, null, null, null, null, null, null,
47 | null, null, true, null, null, null, null, null,
48 | null, null, null, null, null, null, null, null
49 | ]
50 | ];
51 |
--------------------------------------------------------------------------------
/assets/js/null_track.js:
--------------------------------------------------------------------------------
1 | export const nullTrack = [
2 | [
3 | true, null, null, null, null, null, null, true,
4 | true, null, true, null, true, null, null, true,
5 | true, null, null, null, null, null, null, null,
6 | true, null, null, null, null, null, null, true
7 | ],
8 | [
9 | null, null, null, null, null, null, null, null,
10 | null, null, true, true, null, null, null, null,
11 | null, null, null, null, null, null, true, true,
12 | null, true, null, true, null, true, null, null
13 | ],
14 | [
15 | null, null, null, null, null, null, null, null,
16 | null, null, null, null, null, null, null, null,
17 | null, null, null, null, true, null, null, null,
18 | null, null, null, null, null, null, null, null
19 | ],
20 | [
21 | true, null, null, true, null, true, null, null,
22 | null, null, null, null, null, null, null, null,
23 | true, null, null, true, null, null, true, null,
24 | null, null, true, null, null, true, null, null
25 | ],
26 | [
27 | null, null, null, null, null, null, null, null,
28 | null, null, null, null, null, null, null, null,
29 | null, null, null, null, null, null, null, null,
30 | null, null, null, null, true, null, true, null
31 | ],
32 | [
33 | true, null, true, true, true, null, true, null,
34 | true, null, true, null, true, null, true, true,
35 | true, null, true, null, true, null, true, null,
36 | true, true, true, null, true, null, true, true
37 | ],
38 | [
39 | null, null, null, null, null, null, true, null,
40 | null, null, null, null, null, null, null, null,
41 | null, null, true, null, null, null, true, null,
42 | null, null, true, null, null, true, null, null
43 | ],
44 | [
45 | null, null, true, null, null, null, null, null,
46 | null, null, null, null, null, null, null, null,
47 | null, null, true, null, null, null, null, null,
48 | null, null, null, null, null, null, null, null
49 | ]
50 | ];
51 |
--------------------------------------------------------------------------------
/assets/js/patterns.js:
--------------------------------------------------------------------------------
1 | export const demoTrack = [
2 | [
3 | true, null, null, null, null, null, null, true,
4 | true, null, true, null, true, null, null, true,
5 | true, null, null, null, null, null, null, null,
6 | true, null, null, null, null, null, null, true
7 | ],
8 | [
9 | null, null, null, null, null, null, null, null,
10 | null, null, true, true, null, null, null, null,
11 | null, null, null, null, null, null, true, true,
12 | null, true, null, true, null, true, null, null
13 | ],
14 | [
15 | null, null, null, null, true, null, null, null,
16 | null, null, null, null, null, null, null, null,
17 | null, null, null, null, true, null, null, null,
18 | null, null, null, null, null, null, null, null
19 | ],
20 | [
21 | true, null, null, true, null, null, true, null,
22 | null, null, null, null, null, null, null, null,
23 | true, null, null, true, null, null, true, null,
24 | null, null, true, null, null, true, null, null
25 | ],
26 | [
27 | null, null, null, null, null, null, null, null,
28 | null, null, null, null, null, null, null, null,
29 | null, null, null, null, null, null, null, null,
30 | null, null, null, null, true, null, true, null
31 | ],
32 | [
33 | true, null, true, true, true, null, true, null,
34 | true, null, true, null, true, null, true, true,
35 | true, null, true, null, true, null, true, null,
36 | true, true, true, null, true, null, true, true
37 | ],
38 | [
39 | null, null, null, null, null, null, true, null,
40 | null, null, null, null, null, null, null, null,
41 | null, null, true, null, null, null, true, null,
42 | null, null, true, null, null, true, null, null
43 | ],
44 | [
45 | null, null, true, null, null, null, null, null,
46 | null, null, null, null, null, null, null, null,
47 | null, null, true, null, null, null, null, null,
48 | null, null, null, null, null, null, null, null
49 | ]
50 | ];
51 |
--------------------------------------------------------------------------------
/src/components/knob.js:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react';
2 |
3 | class Knob extends Component {
4 | constructor(props) {
5 | super(props);
6 | this.state = {
7 | isDragging: false,
8 | deg: 0
9 | };
10 | this.onMouseDown = this.onMouseDown.bind(this);
11 | this.onMouseUp = this.onMouseUp.bind(this);
12 | this.onMouseMove = this.onMouseMove.bind(this);
13 | this.handleChange = this.handleChange.bind(this);
14 | }
15 |
16 | onMouseDown(e) {
17 | e.preventDefault();
18 | this.setState({ isDragging: true });
19 | }
20 |
21 | onMouseUp(e) {
22 | e.preventDefault();
23 | this.setState({ isDragging: false });
24 | }
25 |
26 | onMouseMove(e) {
27 | const { radius } = this.props;
28 | if (this.state.isDragging) {
29 | const mPos = {x: e.clientX, y: e.clientY};
30 | const atan = Math.atan2(mPos.x - radius, mPos.y - radius) * -(180/ Math.PI);
31 | console.log(atan);
32 | let deg = -atan/(Math.PI/180) + 90;
33 | // final (0-360 positive) degrees from mouse position
34 | // for attraction to multiple of 90 degrees
35 | if (deg === 360) {
36 | deg = 0;
37 | };
38 | this.setState({ deg: deg });
39 | }
40 | };
41 |
42 | handleChange(e) {
43 | const deg = e.target.value;
44 | this.setState({ deg });
45 | };
46 |
47 | render() {
48 | const { deg } = this.state;
49 | const { radius } = this.props;
50 | return (
51 |
52 |
61 |
67 |
68 |
75 |
76 |
77 | );
78 | }
79 | }
80 |
81 | Knob.propTypes = {
82 | value: PropTypes.number,
83 | radius: PropTypes.number
84 | };
85 |
86 | Knob.defaultProps = {
87 | value: 0,
88 | radius: 25
89 | };
90 |
91 | export default Knob;
92 |
--------------------------------------------------------------------------------
/src/components/drum_machine.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 | import Tone from 'tone';
3 | import PositionTransform from '../../assets/js/position';
4 | import { demoTrack } from '../../assets/js/patterns';
5 | import { nullTrack } from '../../assets/js/null_track';
6 | import ChannelRow from './channel_row';
7 | import ProgressBar from './progress_bar';
8 | import ScrewPlate from './screws';
9 | import PlayBar from './playbar';
10 |
11 | class drumMachine extends Component {
12 | constructor(props) {
13 | super(props);
14 | this.abswitch = this.abswitch.bind(this);
15 | this.updatePattern = this.updatePattern.bind(this);
16 | this.startStop = this.startStop.bind(this);
17 | this.changeTempo = this.changeTempo.bind(this);
18 | this.changeVolume = this.changeVolume.bind(this);
19 | this.clearPattern = this.clearPattern.bind(this);
20 | this.positionMarker = this.positionMarker.bind(this);
21 |
22 | this.state = {
23 | bpm: 94,
24 | position: 0,
25 | volume: -6,
26 | playing: false,
27 | bside: false,
28 | currentPattern: demoTrack
29 | };
30 |
31 | this.sampleOrder = ['BD', 'SD', 'CL', 'CA', 'LT', 'CH', 'OH', 'HT'];
32 |
33 | const multSampler = new Tone.MultiPlayer({
34 | urls: {
35 | BD: './assets/samples/Kick.wav',
36 | SD: './assets/samples/Snare.wav',
37 | CL: './assets/samples/Clap.wav',
38 | CA: './assets/samples/Clave.wav',
39 | LT: './assets/samples/LowTom.wav',
40 | CH: './assets/samples/ClosedHat.wav',
41 | OH: './assets/samples/OpenHat.wav',
42 | HT: './assets/samples/HighTom.wav'
43 | }
44 | }).toMaster();
45 |
46 | const steps = Array(32).fill(1).map((v, i) => {
47 | return i;
48 | });
49 |
50 | const getColumns = (track) => {
51 | const result = [];
52 | for (let i = 0; i < 32; i += 1) {
53 | result.push(track.map((v, idx) => { return v[i] ? this.sampleOrder[idx] : null }).filter(v => v));
54 | }
55 | return result;
56 | };
57 |
58 | this.columnPattern = getColumns(this.state.currentPattern);
59 |
60 | this.playSeq = new Tone.Sequence((time, value) => {
61 | this.columnPattern[value].forEach((v) => { return multSampler.start(v, time, 0, '16n', 0);});
62 | }, steps, '16n');
63 |
64 | this.playSeq.start();
65 | this.playSeq.loop = true;
66 |
67 | Tone.Transport.setLoopPoints(0, '2m');
68 | Tone.Transport.loop = true;
69 | Tone.Transport.scheduleRepeat(this.positionMarker, '16n');
70 | Tone.Transport.bpm.value = this.state.bpm;
71 | Tone.Master.volume.value = this.state.volume;
72 | }
73 |
74 | componentDidMount() {
75 | document.addEventListener('keydown', (e) => {
76 | const pressed = e.key;
77 | if (pressed === ' ') {
78 | this.startStop();
79 | }
80 | });
81 | }
82 |
83 | clearPattern() {
84 | this.setState({ currentPattern: nullTrack });
85 | }
86 |
87 | positionMarker() {
88 | this.setState({ position: PositionTransform[Tone.Transport.position.slice(0, 5)] });
89 | }
90 |
91 | startStop() {
92 | if (this.state.playing) {
93 | Tone.Transport.stop();
94 | this.setState({ playing: false });
95 | }
96 | else {
97 | Tone.Transport.start('+0.25');
98 | this.setState({ playing: true });
99 | }
100 | }
101 |
102 | changeTempo(e) {
103 | let newTempo = parseInt(e.currentTarget.value, 10);
104 | if (isNaN(newTempo)) {
105 | newTempo = 10;
106 | }
107 | if (newTempo > 200) {
108 | newTempo = 200;
109 | }
110 | Tone.Transport.bpm.value = newTempo;
111 | this.setState({ bpm: newTempo });
112 | }
113 |
114 | updatePattern(event) {
115 | const channelNum = parseInt(event.currentTarget.dataset.channel, 10);
116 | const stepNum = parseInt(event.currentTarget.dataset.stepindx, 10);
117 | const cpattern = this.state.currentPattern;
118 | if (cpattern[channelNum][stepNum]) {
119 | cpattern[channelNum][stepNum] = null;
120 | const colpattemp = this.columnPattern[stepNum].slice();
121 | const target = colpattemp.indexOf(this.sampleOrder[channelNum]);
122 | colpattemp.splice(target, 1);
123 | this.columnPattern[stepNum] = colpattemp;
124 | this.setState({ currentPattern: cpattern });
125 | }
126 | else {
127 | const newSamp = this.sampleOrder[channelNum];
128 | this.columnPattern[stepNum].push(newSamp);
129 | cpattern[channelNum][stepNum] = true;
130 | this.setState({ currentPattern: cpattern });
131 | }
132 | this.setState({ currentPattern: cpattern });
133 | }
134 |
135 | abswitch() {
136 | this.setState({ bside: !this.state.bside });
137 | }
138 |
139 | changeVolume(e, value) {
140 | this.setState({ volume: value });
141 | if (value < -40) {
142 | value = -100;
143 | }
144 | Tone.Master.volume.value = value;
145 | }
146 |
147 | render() {
148 | function makeSeqRow(v, i) {
149 | let pattern;
150 | if (this.state.bside) {
151 | pattern = v.slice(16);
152 | }
153 | else {
154 | pattern = v.slice(0, 16);
155 | }
156 | return (
157 |
164 | );
165 | }
166 |
167 | return (
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 | {this.state.currentPattern.map(makeSeqRow, this)}
176 |
177 |
183 |
184 |
185 |
186 |
187 |
188 | );
189 | }
190 | }
191 |
192 | export default drumMachine;
193 |
--------------------------------------------------------------------------------
/dist/manifest.9b0443ed5b4bcfffb491.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // install a JSONP callback for chunk loading
3 | /******/ var parentJsonpFunction = window["webpackJsonp"];
4 | /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
5 | /******/ // add "moreModules" to the modules object,
6 | /******/ // then flag all "chunkIds" as loaded and fire callback
7 | /******/ var moduleId, chunkId, i = 0, resolves = [], result;
8 | /******/ for(;i < chunkIds.length; i++) {
9 | /******/ chunkId = chunkIds[i];
10 | /******/ if(installedChunks[chunkId])
11 | /******/ resolves.push(installedChunks[chunkId][0]);
12 | /******/ installedChunks[chunkId] = 0;
13 | /******/ }
14 | /******/ for(moduleId in moreModules) {
15 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
16 | /******/ modules[moduleId] = moreModules[moduleId];
17 | /******/ }
18 | /******/ }
19 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
20 | /******/ while(resolves.length)
21 | /******/ resolves.shift()();
22 | /******/ if(executeModules) {
23 | /******/ for(i=0; i < executeModules.length; i++) {
24 | /******/ result = __webpack_require__(__webpack_require__.s = executeModules[i]);
25 | /******/ }
26 | /******/ }
27 | /******/ return result;
28 | /******/ };
29 |
30 | /******/ // The module cache
31 | /******/ var installedModules = {};
32 |
33 | /******/ // objects to store loaded and loading chunks
34 | /******/ var installedChunks = {
35 | /******/ 2: 0
36 | /******/ };
37 |
38 | /******/ // The require function
39 | /******/ function __webpack_require__(moduleId) {
40 |
41 | /******/ // Check if module is in cache
42 | /******/ if(installedModules[moduleId])
43 | /******/ return installedModules[moduleId].exports;
44 |
45 | /******/ // Create a new module (and put it into the cache)
46 | /******/ var module = installedModules[moduleId] = {
47 | /******/ i: moduleId,
48 | /******/ l: false,
49 | /******/ exports: {}
50 | /******/ };
51 |
52 | /******/ // Execute the module function
53 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
54 |
55 | /******/ // Flag the module as loaded
56 | /******/ module.l = true;
57 |
58 | /******/ // Return the exports of the module
59 | /******/ return module.exports;
60 | /******/ }
61 |
62 | /******/ // This file contains only the entry chunk.
63 | /******/ // The chunk loading function for additional chunks
64 | /******/ __webpack_require__.e = function requireEnsure(chunkId) {
65 | /******/ if(installedChunks[chunkId] === 0)
66 | /******/ return Promise.resolve();
67 |
68 | /******/ // an Promise means "currently loading".
69 | /******/ if(installedChunks[chunkId]) {
70 | /******/ return installedChunks[chunkId][2];
71 | /******/ }
72 | /******/ // start chunk loading
73 | /******/ var head = document.getElementsByTagName('head')[0];
74 | /******/ var script = document.createElement('script');
75 | /******/ script.type = 'text/javascript';
76 | /******/ script.charset = 'utf-8';
77 | /******/ script.async = true;
78 | /******/ script.timeout = 120000;
79 |
80 | /******/ if (__webpack_require__.nc) {
81 | /******/ script.setAttribute("nonce", __webpack_require__.nc);
82 | /******/ }
83 | /******/ script.src = __webpack_require__.p + "" + chunkId + "." + {"0":"502984d7f9ccb429d440","1":"be9505c48da7088d1b85"}[chunkId] + ".js";
84 | /******/ var timeout = setTimeout(onScriptComplete, 120000);
85 | /******/ script.onerror = script.onload = onScriptComplete;
86 | /******/ function onScriptComplete() {
87 | /******/ // avoid mem leaks in IE.
88 | /******/ script.onerror = script.onload = null;
89 | /******/ clearTimeout(timeout);
90 | /******/ var chunk = installedChunks[chunkId];
91 | /******/ if(chunk !== 0) {
92 | /******/ if(chunk) chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
93 | /******/ installedChunks[chunkId] = undefined;
94 | /******/ }
95 | /******/ };
96 | /******/ head.appendChild(script);
97 |
98 | /******/ var promise = new Promise(function(resolve, reject) {
99 | /******/ installedChunks[chunkId] = [resolve, reject];
100 | /******/ });
101 | /******/ return installedChunks[chunkId][2] = promise;
102 | /******/ };
103 |
104 | /******/ // expose the modules object (__webpack_modules__)
105 | /******/ __webpack_require__.m = modules;
106 |
107 | /******/ // expose the module cache
108 | /******/ __webpack_require__.c = installedModules;
109 |
110 | /******/ // identity function for calling harmony imports with the correct context
111 | /******/ __webpack_require__.i = function(value) { return value; };
112 |
113 | /******/ // define getter function for harmony exports
114 | /******/ __webpack_require__.d = function(exports, name, getter) {
115 | /******/ if(!__webpack_require__.o(exports, name)) {
116 | /******/ Object.defineProperty(exports, name, {
117 | /******/ configurable: false,
118 | /******/ enumerable: true,
119 | /******/ get: getter
120 | /******/ });
121 | /******/ }
122 | /******/ };
123 |
124 | /******/ // getDefaultExport function for compatibility with non-harmony modules
125 | /******/ __webpack_require__.n = function(module) {
126 | /******/ var getter = module && module.__esModule ?
127 | /******/ function getDefault() { return module['default']; } :
128 | /******/ function getModuleExports() { return module; };
129 | /******/ __webpack_require__.d(getter, 'a', getter);
130 | /******/ return getter;
131 | /******/ };
132 |
133 | /******/ // Object.prototype.hasOwnProperty.call
134 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
135 |
136 | /******/ // __webpack_public_path__
137 | /******/ __webpack_require__.p = "";
138 |
139 | /******/ // on error function for async loading
140 | /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
141 | /******/ })
142 | /************************************************************************/
143 | /******/ ([]);
--------------------------------------------------------------------------------
/assets/style/style.css:
--------------------------------------------------------------------------------
1 | html,
2 | body, #root {
3 | width:100%;
4 | background-color:black;
5 | display:flex;
6 | justify-content:center;
7 | }
8 |
9 | .rackcabinet {
10 | width: 85%;
11 | background-color: #854500;
12 | background-image: url('../images/dark-wood.png');
13 | margin-top:8px;
14 | padding:0 2px 0 2px;
15 | display:flex;
16 | justify-content:center;
17 | flex-wrap:wrap;
18 | border-radius:10px;
19 | }
20 |
21 | .rack {
22 | display:flex;
23 | justify-content:center;
24 | width:92%;
25 | flex-wrap:wrap;
26 | background-color:black;
27 | }
28 |
29 | .drumrack {
30 | width: 100%;
31 | margin-right:6px;
32 | margin-left:6px;
33 | padding:4px 2px 4px 2px;
34 | border-radius: 9px;
35 | display: flex;
36 | position:relative;
37 | justify-content: center;
38 | flex-direction:row;
39 | flex-wrap:wrap;
40 | background-color: #404143;
41 | }
42 |
43 | .screwplate {
44 | width:99%;
45 | display:flex;
46 | position:relative;
47 | justify-content:space-between;
48 | }
49 |
50 | .screw {
51 | height:20px;
52 | width:20px;
53 | background-image: -webkit-radial-gradient( 50% 0%, 8% 50%, hsla(0,0%,100%,.9) 0%, hsla(0,0%,100%,0) 100%),
54 | -webkit-radial-gradient( 50% 100%, 12% 50%, hsla(0,0%,100%,.6) 0%, hsla(0,0%,100%,0) 100%),
55 | -webkit-radial-gradient( 0% 50%, 50% 7%, hsla(0,0%,100%,.5) 0%, hsla(0,0%,100%,0) 100%),
56 | -webkit-radial-gradient( 100% 50%, 50% 5%, hsla(0,0%,100%,.5) 0%, hsla(0,0%,100%,0) 100%),
57 | -webkit-repeating-radial-gradient( 50% 50%, 100% 100%, hsla(0,0%, 0%,0) 0%, hsla(0,0%, 0%,0) 3%, hsla(0,0%, 0%,.1) 3.5%),
58 | -webkit-repeating-radial-gradient( 50% 50%, 100% 100%, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 6%, hsla(0,0%,100%,.1) 7.5%),
59 | -webkit-repeating-radial-gradient( 50% 50%, 100% 100%, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 1.2%, hsla(0,0%,100%,.2) 2.2%),
60 | -webkit-radial-gradient( 50% 50%, 200% 50%, hsla(0,0%,90%,1) 5%, hsla(0,0%,85%,1) 30%, hsla(0,0%,60%,1) 100%);
61 | border-radius:50%;
62 | position:relative;
63 | box-shadow:0 0 10px 0 #222;
64 | }
65 |
66 | .sequencerrow {
67 | width:90%;
68 | display:flex;
69 | flex-direction: row;
70 | justify-content:center;
71 | }
72 |
73 | .stepbutton {
74 | cursor: pointer;
75 | width: 5vw;
76 | height: 55px;
77 | background-color: grey;
78 | margin: 5px;
79 | border-radius: 5px;
80 | overflow: hidden;
81 | display:flex;
82 | justify-content:center;
83 | align-items:flex-start;
84 | position: relative;
85 | box-shadow: inset 0 -2px 2px rgba(0, 0, 0, 0.9), inset 0 20px 0 rgba(255, 255, 255, 0.2), inset 0 24px 0 rgba(255, 255, 255, 0.3);
86 | }
87 |
88 | .lightoff {
89 | display: block;
90 | position: absolute;
91 | background: #4a2b2b;
92 | top:10%;
93 | border-radius: 50%;
94 | width: 10px;
95 | height: 10px;
96 | border: 2px rgba(0, 0, 0, 0.15) solid;
97 | }
98 |
99 | .lighton {
100 | display: block;
101 | position: absolute;
102 | background: hsla(0, 87%, 47%, 0.94);
103 | border-radius: 50%;
104 | width: 10px;
105 | height: 10px;
106 | top: 10%;
107 | border: 2px rgba(0, 0, 0, 0.15) solid;
108 | }
109 |
110 | .stepbutton:nth-of-type(n):nth-of-type(-n+4) {
111 | background-color: #DD1D00;
112 | }
113 |
114 | .stepbutton:nth-of-type(n+5):nth-of-type(-n+8) {
115 | background-color: #F27900;
116 | }
117 |
118 | .stepbutton:nth-of-type(n+9):nth-of-type(-n+12) {
119 | background-color: #DDDA00;
120 | }
121 |
122 | .stepbutton:nth-of-type(n+13):nth-of-type(-n+16) {
123 | background-color: #E6E8BF;
124 | }
125 |
126 | .progressbar {
127 | width:90%;
128 | display:flex;
129 | flex-direction:row;
130 | justify-content:center;
131 | }
132 |
133 | .progresslight {
134 | width: 5vw;
135 | height: 10px;
136 | position:relative;
137 | margin:5px;
138 | border-radius: 2px;
139 | background-color: #1c3030;
140 | box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.9), inset 0 28px 0 rgba(255, 255, 255, 0.2), inset 0 28px 0 rgba(255, 255, 255, 0.3);
141 | }
142 |
143 | .progresslighton {
144 | width: 5vw;
145 | height: 10px;
146 | margin:5px;
147 | position:relative;
148 | border-radius: 2px;
149 | background-color: red;
150 | box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.9), inset 0 28px 0 rgba(221, 29, 0, 0.2), inset 0 28px 0 rgba(255, 255, 255, 0.3);
151 | }
152 |
153 | .drumrackbar {
154 | width:90%;
155 | margin-top:15px;
156 | display:flex;
157 | justify-content: flex-start;
158 | }
159 |
160 | .drumracklabel {
161 | height: 55px;
162 | font-family: 'Monoton', cursive;
163 | bottom:4px;
164 | font-size: 48px;
165 | color: black;
166 | position:relative;
167 | }
168 |
169 | .slash {
170 | font-size:34px;
171 | padding-left:10px;
172 | padding-right:10px;
173 | margin-top: 6px;
174 | }
175 |
176 | .playstopbutton {
177 | width: 9em;
178 | padding-left:4px;
179 | padding-right:4px;
180 | cursor: pointer;
181 | align-self: flex-end;
182 | font-family: 'Orbitron';
183 | height: 55px;
184 | margin-top:1px;
185 | position:relative;
186 | border-radius: 5px;
187 | background-color:silver;
188 | display:flex;
189 | justify-content:center;
190 | align-items:center;
191 | box-shadow: inset 0 -2px 2px rgba(0, 0, 0, 0.9), inset 0 180px 0 rgba(255, 255, 255, 0.2), inset 0 190px 0 rgba(255, 255, 255, 0.3);
192 | }
193 |
194 | .bpmplaybar{
195 | display:flex;
196 | flex-direction:row;
197 | justify-content:center;
198 | }
199 |
200 | .tempolabel {
201 | font-family: 'Orbitron', sans-serif;
202 | height: 55px;
203 | font-size: 32px;
204 | background-color:black;
205 | padding-right:10px;
206 | border-radius: 5px;
207 | color: #DD1D00;
208 | margin-right: 7px;
209 | width: 3em;
210 | text-align:right;
211 | border: none;
212 | display:flex;
213 | justify-content:center;
214 | align-items:center;
215 | border-color: transparent;
216 | }
217 |
218 | .togglebox {
219 | margin:0 20px 0 20px ;
220 | display:flex;
221 | flex-direction:row;
222 | justify-content:space-between;
223 | height:55px;
224 | position:relative;
225 | width:100px;
226 | }
227 |
228 | .lettera, .letterb {
229 | margin-top:19px;
230 | color:black;
231 | font-family: 'Orbitron', sans-serif;
232 | text-transform: uppercase;
233 | font-size: 24px;
234 | font-weight: 300;
235 | cursor: pointer;
236 | }
237 |
238 | .toggle-slider {
239 | width: 42px;
240 | height: 20px;
241 | border-radius: 12px;
242 | background: silver;
243 | box-shadow: 1px 1px 6px #aaa;
244 | transition: all 100ms ease-in-out;
245 | position: relative;
246 | top: 50%;
247 | -webkit-transform: translateY(-50%);
248 | -ms-transform: translateY(-50%);
249 | transform: translateY(-50%);
250 | }
251 |
252 | .toggle-slider-button {
253 | position: absolute;
254 | left: 1px;
255 | top: 0px;
256 | width: 18px;
257 | height: 18px;
258 | background: black;
259 | border: 1px solid #404143;
260 | border-radius: 50%;
261 | box-shadow: 1px 1px 6px #aaa;
262 | z-index: 1;
263 | transition: all 100ms ease-in-out;
264 | }
265 |
266 | .toggled .toggle-slider {
267 | background: #388E3C;
268 | }
269 |
270 | .toggled .toggle-slider-button {
271 | left: calc(100% - 19px);
272 | }
273 |
274 | .abswitch{
275 | height:50px;
276 | width:100px;
277 | background-color:blue;
278 | border:1px solid green;
279 | }
280 |
281 | textarea:focus, input:focus{
282 | outline: none;
283 | }
284 |
285 | input::-webkit-outer-spin-button,
286 | input::-webkit-inner-spin-button {
287 | display: none; /**<- Crashes Chrome on hover **/
288 | -webkit-appearance: none;
289 | margin: 0; /**<-- Apparently some margin are still there even though it's hidden **/
290 | }
291 |
292 | @media only screen and (min-width: 1550px) {
293 | .drumrackbar{
294 | margin-left:19em;
295 | margin-right:19em;
296 | }
297 | }
298 |
299 | @media only screen and (min-width: 1314px) {
300 | .drumrackbar{
301 | justify-content:space-around;
302 | margin-left:7em;
303 | margin-right:7em;
304 | }
305 | }
306 |
307 | @media only screen and (min-width: 1280px) {
308 |
309 | }
310 |
311 | @media only screen and (max-width: 1024px) {
312 | .drumrackbar{
313 | flex-wrap:wrap;
314 | }
315 | .drumracklabel {
316 | font-size:40px;
317 | }
318 | }
319 |
320 | @media only screen and (max-width: 960px) {
321 | .drumracklabel{
322 | font-size:30px;
323 | }
324 | .lighton {
325 | width:5px;
326 | height:5px;
327 | }
328 | .lightoff {
329 | width:5px;
330 | height:5px;
331 | }
332 | }
333 |
334 | @media only screen and (max-width: 700px) {
335 | .sequencerrow {
336 | width:100%;
337 | }
338 | .progressbar {
339 | width:100%;
340 | }
341 | .rackcabinet {
342 | width:98%;
343 | }
344 | }
345 |
--------------------------------------------------------------------------------
/dist/style.css:
--------------------------------------------------------------------------------
1 | html,
2 | body, #root {
3 | width:100%;
4 | background-color:black;
5 | display:flex;
6 | justify-content:center;
7 | }
8 |
9 | .rackcabinet {
10 | width: 85%;
11 | background-color: #854500;
12 | background-image: url(e3577ddd019c610cedbeb38ebff4e2ef.png);
13 | margin-top:8px;
14 | padding:0 2px 0 2px;
15 | display:flex;
16 | justify-content:center;
17 | flex-wrap:wrap;
18 | border-radius:10px;
19 | }
20 |
21 | .rack {
22 | display:flex;
23 | justify-content:center;
24 | width:92%;
25 | flex-wrap:wrap;
26 | background-color:black;
27 | }
28 |
29 | .drumrack {
30 | width: 100%;
31 | margin-right:6px;
32 | margin-left:6px;
33 | padding:4px 2px 4px 2px;
34 | border-radius: 9px;
35 | display: flex;
36 | position:relative;
37 | justify-content: center;
38 | flex-direction:row;
39 | flex-wrap:wrap;
40 | background-color: #404143;
41 | }
42 |
43 | .screwplate {
44 | width:99%;
45 | display:flex;
46 | position:relative;
47 | justify-content:space-between;
48 | }
49 |
50 | .screw {
51 | height:20px;
52 | width:20px;
53 | background-image: -webkit-radial-gradient( 50% 0%, 8% 50%, hsla(0,0%,100%,.9) 0%, hsla(0,0%,100%,0) 100%),
54 | -webkit-radial-gradient( 50% 100%, 12% 50%, hsla(0,0%,100%,.6) 0%, hsla(0,0%,100%,0) 100%),
55 | -webkit-radial-gradient( 0% 50%, 50% 7%, hsla(0,0%,100%,.5) 0%, hsla(0,0%,100%,0) 100%),
56 | -webkit-radial-gradient( 100% 50%, 50% 5%, hsla(0,0%,100%,.5) 0%, hsla(0,0%,100%,0) 100%),
57 | -webkit-repeating-radial-gradient( 50% 50%, 100% 100%, hsla(0,0%, 0%,0) 0%, hsla(0,0%, 0%,0) 3%, hsla(0,0%, 0%,.1) 3.5%),
58 | -webkit-repeating-radial-gradient( 50% 50%, 100% 100%, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 6%, hsla(0,0%,100%,.1) 7.5%),
59 | -webkit-repeating-radial-gradient( 50% 50%, 100% 100%, hsla(0,0%,100%,0) 0%, hsla(0,0%,100%,0) 1.2%, hsla(0,0%,100%,.2) 2.2%),
60 | -webkit-radial-gradient( 50% 50%, 200% 50%, hsla(0,0%,90%,1) 5%, hsla(0,0%,85%,1) 30%, hsla(0,0%,60%,1) 100%);
61 | border-radius:50%;
62 | position:relative;
63 | box-shadow:0 0 10px 0 #222;
64 | }
65 |
66 | .sequencerrow {
67 | width:90%;
68 | display:flex;
69 | flex-direction: row;
70 | justify-content:center;
71 | }
72 |
73 | .stepbutton {
74 | cursor: pointer;
75 | width: 5vw;
76 | height: 55px;
77 | background-color: grey;
78 | margin: 5px;
79 | border-radius: 5px;
80 | overflow: hidden;
81 | display:flex;
82 | justify-content:center;
83 | align-items:flex-start;
84 | position: relative;
85 | box-shadow: inset 0 -2px 2px rgba(0, 0, 0, 0.9), inset 0 20px 0 rgba(255, 255, 255, 0.2), inset 0 24px 0 rgba(255, 255, 255, 0.3);
86 | }
87 |
88 | .lightoff {
89 | display: block;
90 | position: absolute;
91 | background: #4a2b2b;
92 | top:10%;
93 | border-radius: 50%;
94 | width: 10px;
95 | height: 10px;
96 | border: 2px rgba(0, 0, 0, 0.15) solid;
97 | }
98 |
99 | .lighton {
100 | display: block;
101 | position: absolute;
102 | background: hsla(0, 87%, 47%, 0.94);
103 | border-radius: 50%;
104 | width: 10px;
105 | height: 10px;
106 | top: 10%;
107 | border: 2px rgba(0, 0, 0, 0.15) solid;
108 | }
109 |
110 | .stepbutton:nth-of-type(n):nth-of-type(-n+4) {
111 | background-color: #DD1D00;
112 | }
113 |
114 | .stepbutton:nth-of-type(n+5):nth-of-type(-n+8) {
115 | background-color: #F27900;
116 | }
117 |
118 | .stepbutton:nth-of-type(n+9):nth-of-type(-n+12) {
119 | background-color: #DDDA00;
120 | }
121 |
122 | .stepbutton:nth-of-type(n+13):nth-of-type(-n+16) {
123 | background-color: #E6E8BF;
124 | }
125 |
126 | .progressbar {
127 | width:90%;
128 | display:flex;
129 | flex-direction:row;
130 | justify-content:center;
131 | }
132 |
133 | .progresslight {
134 | width: 5vw;
135 | height: 10px;
136 | position:relative;
137 | margin:5px;
138 | border-radius: 2px;
139 | background-color: #1c3030;
140 | box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.9), inset 0 28px 0 rgba(255, 255, 255, 0.2), inset 0 28px 0 rgba(255, 255, 255, 0.3);
141 | }
142 |
143 | .progresslighton {
144 | width: 5vw;
145 | height: 10px;
146 | margin:5px;
147 | position:relative;
148 | border-radius: 2px;
149 | background-color: red;
150 | box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.9), inset 0 28px 0 rgba(221, 29, 0, 0.2), inset 0 28px 0 rgba(255, 255, 255, 0.3);
151 | }
152 |
153 | .drumrackbar {
154 | width:90%;
155 | margin-top:15px;
156 | display:flex;
157 | justify-content: flex-start;
158 | }
159 |
160 | .drumracklabel {
161 | height: 55px;
162 | font-family: 'Monoton', cursive;
163 | bottom:4px;
164 | font-size: 48px;
165 | color: black;
166 | position:relative;
167 | }
168 |
169 | .slash {
170 | font-size:34px;
171 | padding-left:10px;
172 | padding-right:10px;
173 | margin-top: 6px;
174 | }
175 |
176 | .playstopbutton {
177 | width: 9em;
178 | padding-left:4px;
179 | padding-right:4px;
180 | cursor: pointer;
181 | align-self: flex-end;
182 | font-family: 'Orbitron';
183 | height: 55px;
184 | margin-top:1px;
185 | position:relative;
186 | border-radius: 5px;
187 | background-color:silver;
188 | display:flex;
189 | justify-content:center;
190 | align-items:center;
191 | box-shadow: inset 0 -2px 2px rgba(0, 0, 0, 0.9), inset 0 180px 0 rgba(255, 255, 255, 0.2), inset 0 190px 0 rgba(255, 255, 255, 0.3);
192 | }
193 |
194 | .bpmplaybar{
195 | display:flex;
196 | flex-direction:row;
197 | justify-content:center;
198 | }
199 |
200 | .tempolabel {
201 | font-family: 'Orbitron', sans-serif;
202 | height: 55px;
203 | font-size: 32px;
204 | background-color:black;
205 | padding-right:10px;
206 | border-radius: 5px;
207 | color: #DD1D00;
208 | margin-right: 7px;
209 | width: 3em;
210 | text-align:right;
211 | border: none;
212 | display:flex;
213 | justify-content:center;
214 | align-items:center;
215 | border-color: transparent;
216 | }
217 |
218 | .togglebox {
219 | margin:0 20px 0 20px ;
220 | display:flex;
221 | flex-direction:row;
222 | justify-content:space-between;
223 | height:55px;
224 | position:relative;
225 | width:100px;
226 | }
227 |
228 | .lettera, .letterb {
229 | margin-top:19px;
230 | color:black;
231 | font-family: 'Orbitron', sans-serif;
232 | text-transform: uppercase;
233 | font-size: 24px;
234 | font-weight: 300;
235 | cursor: pointer;
236 | }
237 |
238 | .toggle-slider {
239 | width: 42px;
240 | height: 20px;
241 | border-radius: 12px;
242 | background: silver;
243 | box-shadow: 1px 1px 6px #aaa;
244 | transition: all 100ms ease-in-out;
245 | position: relative;
246 | top: 50%;
247 | -webkit-transform: translateY(-50%);
248 | -ms-transform: translateY(-50%);
249 | transform: translateY(-50%);
250 | }
251 |
252 | .toggle-slider-button {
253 | position: absolute;
254 | left: 1px;
255 | top: 0px;
256 | width: 18px;
257 | height: 18px;
258 | background: black;
259 | border: 1px solid #404143;
260 | border-radius: 50%;
261 | box-shadow: 1px 1px 6px #aaa;
262 | z-index: 1;
263 | transition: all 100ms ease-in-out;
264 | }
265 |
266 | .toggled .toggle-slider {
267 | background: #388E3C;
268 | }
269 |
270 | .toggled .toggle-slider-button {
271 | left: calc(100% - 19px);
272 | }
273 |
274 | .abswitch{
275 | height:50px;
276 | width:100px;
277 | background-color:blue;
278 | border:1px solid green;
279 | }
280 |
281 | textarea:focus, input:focus{
282 | outline: none;
283 | }
284 |
285 | input::-webkit-outer-spin-button,
286 | input::-webkit-inner-spin-button {
287 | display: none; /**<- Crashes Chrome on hover **/
288 | -webkit-appearance: none;
289 | margin: 0; /**<-- Apparently some margin are still there even though it's hidden **/
290 | }
291 |
292 | @media only screen and (min-width: 1550px) {
293 | .drumrackbar{
294 | margin-left:19em;
295 | margin-right:19em;
296 | }
297 | }
298 |
299 | @media only screen and (min-width: 1314px) {
300 | .drumrackbar{
301 | justify-content:space-around;
302 | margin-left:7em;
303 | margin-right:7em;
304 | }
305 | }
306 |
307 | @media only screen and (min-width: 1280px) {
308 |
309 | }
310 |
311 | @media only screen and (max-width: 1024px) {
312 | .drumrackbar{
313 | flex-wrap:wrap;
314 | }
315 | .drumracklabel {
316 | font-size:40px;
317 | }
318 | }
319 |
320 | @media only screen and (max-width: 960px) {
321 | .drumracklabel{
322 | font-size:30px;
323 | }
324 | .lighton {
325 | width:5px;
326 | height:5px;
327 | }
328 | .lightoff {
329 | width:5px;
330 | height:5px;
331 | }
332 | }
333 |
334 | @media only screen and (max-width: 700px) {
335 | .sequencerrow {
336 | width:100%;
337 | }
338 | .progressbar {
339 | width:100%;
340 | }
341 | .rackcabinet {
342 | width:98%;
343 | }
344 | }
345 |
--------------------------------------------------------------------------------
/dist/bundle.be9505c48da7088d1b85.js:
--------------------------------------------------------------------------------
1 | webpackJsonp([1,2],{
2 |
3 | /***/ 188:
4 | /***/ function(module, exports, __webpack_require__) {
5 |
6 | "use strict";
7 |
8 |
9 | var _react = __webpack_require__(11);
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | var _reactDom = __webpack_require__(32);
14 |
15 | var _reactDom2 = _interopRequireDefault(_reactDom);
16 |
17 | var _drum_machine = __webpack_require__(82);
18 |
19 | var _drum_machine2 = _interopRequireDefault(_drum_machine);
20 |
21 | __webpack_require__(83);
22 |
23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24 |
25 | var App = function App() {
26 | return _react2.default.createElement(_drum_machine2.default, null);
27 | };
28 |
29 | _reactDom2.default.render(_react2.default.createElement(App, null), document.getElementById('root'));
30 |
31 | /***/ },
32 |
33 | /***/ 82:
34 | /***/ function(module, exports, __webpack_require__) {
35 |
36 | "use strict";
37 |
38 |
39 | Object.defineProperty(exports, "__esModule", {
40 | value: true
41 | });
42 |
43 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
44 |
45 | var _react = __webpack_require__(11);
46 |
47 | var _react2 = _interopRequireDefault(_react);
48 |
49 | var _tone = __webpack_require__(54);
50 |
51 | var _tone2 = _interopRequireDefault(_tone);
52 |
53 | var _position = __webpack_require__(86);
54 |
55 | var _position2 = _interopRequireDefault(_position);
56 |
57 | var _patterns = __webpack_require__(85);
58 |
59 | var _null_track = __webpack_require__(84);
60 |
61 | var _channel_row = __webpack_require__(87);
62 |
63 | var _channel_row2 = _interopRequireDefault(_channel_row);
64 |
65 | var _progress_bar = __webpack_require__(89);
66 |
67 | var _progress_bar2 = _interopRequireDefault(_progress_bar);
68 |
69 | var _screws = __webpack_require__(90);
70 |
71 | var _screws2 = _interopRequireDefault(_screws);
72 |
73 | var _playbar = __webpack_require__(88);
74 |
75 | var _playbar2 = _interopRequireDefault(_playbar);
76 |
77 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
78 |
79 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
80 |
81 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
82 |
83 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
84 |
85 | var drumMachine = function (_Component) {
86 | _inherits(drumMachine, _Component);
87 |
88 | function drumMachine(props) {
89 | _classCallCheck(this, drumMachine);
90 |
91 | var _this = _possibleConstructorReturn(this, (drumMachine.__proto__ || Object.getPrototypeOf(drumMachine)).call(this, props));
92 |
93 | _this.abswitch = _this.abswitch.bind(_this);
94 | _this.updatePattern = _this.updatePattern.bind(_this);
95 | _this.startStop = _this.startStop.bind(_this);
96 | _this.changeTempo = _this.changeTempo.bind(_this);
97 | _this.changeVolume = _this.changeVolume.bind(_this);
98 | _this.clearPattern = _this.clearPattern.bind(_this);
99 | _this.positionMarker = _this.positionMarker.bind(_this);
100 |
101 | _this.state = {
102 | bpm: 94,
103 | position: 0,
104 | volume: -6,
105 | playing: false,
106 | bside: false,
107 | currentPattern: _patterns.demoTrack
108 | };
109 |
110 | _this.sampleOrder = ['BD', 'SD', 'CL', 'CA', 'LT', 'CH', 'OH', 'HT'];
111 |
112 | var multSampler = new _tone2.default.MultiPlayer({
113 | urls: {
114 | BD: './assets/samples/Kick.wav',
115 | SD: './assets/samples/Snare.wav',
116 | CL: './assets/samples/Clap.wav',
117 | CA: './assets/samples/Clave.wav',
118 | LT: './assets/samples/LowTom.wav',
119 | CH: './assets/samples/ClosedHat.wav',
120 | OH: './assets/samples/OpenHat.wav',
121 | HT: './assets/samples/HighTom.wav'
122 | }
123 | }).toMaster();
124 |
125 | var steps = Array(32).fill(1).map(function (v, i) {
126 | return i;
127 | });
128 |
129 | var getColumns = function getColumns(track) {
130 | var result = [];
131 |
132 | var _loop = function _loop(i) {
133 | result.push(track.map(function (v, idx) {
134 | return v[i] ? _this.sampleOrder[idx] : null;
135 | }).filter(function (v) {
136 | return v;
137 | }));
138 | };
139 |
140 | for (var i = 0; i < 32; i += 1) {
141 | _loop(i);
142 | }
143 | return result;
144 | };
145 |
146 | _this.columnPattern = getColumns(_this.state.currentPattern);
147 |
148 | _this.playSeq = new _tone2.default.Sequence(function (time, value) {
149 | _this.columnPattern[value].forEach(function (v) {
150 | return multSampler.start(v, time, 0, '16n', 0);
151 | });
152 | }, steps, '16n');
153 |
154 | _this.playSeq.start();
155 | _this.playSeq.loop = true;
156 |
157 | _tone2.default.Transport.setLoopPoints(0, '2m');
158 | _tone2.default.Transport.loop = true;
159 | _tone2.default.Transport.scheduleRepeat(_this.positionMarker, '16n');
160 | _tone2.default.Transport.bpm.value = _this.state.bpm;
161 | _tone2.default.Master.volume.value = _this.state.volume;
162 | return _this;
163 | }
164 |
165 | _createClass(drumMachine, [{
166 | key: 'componentDidMount',
167 | value: function componentDidMount() {
168 | var _this2 = this;
169 |
170 | document.addEventListener('keydown', function (e) {
171 | var pressed = e.key;
172 | if (pressed === ' ') {
173 | _this2.startStop();
174 | }
175 | });
176 | }
177 | }, {
178 | key: 'clearPattern',
179 | value: function clearPattern() {
180 | this.setState({ currentPattern: _null_track.nullTrack });
181 | }
182 | }, {
183 | key: 'positionMarker',
184 | value: function positionMarker() {
185 | this.setState({ position: _position2.default[_tone2.default.Transport.position.slice(0, 5)] });
186 | }
187 | }, {
188 | key: 'startStop',
189 | value: function startStop() {
190 | if (this.state.playing) {
191 | _tone2.default.Transport.stop();
192 | this.setState({ playing: false });
193 | } else {
194 | _tone2.default.Transport.start('+0.25');
195 | this.setState({ playing: true });
196 | }
197 | }
198 | }, {
199 | key: 'changeTempo',
200 | value: function changeTempo(e) {
201 | var newTempo = parseInt(e.currentTarget.value, 10);
202 | if (isNaN(newTempo)) {
203 | newTempo = 10;
204 | }
205 | if (newTempo > 200) {
206 | newTempo = 200;
207 | }
208 | _tone2.default.Transport.bpm.value = newTempo;
209 | this.setState({ bpm: newTempo });
210 | }
211 | }, {
212 | key: 'updatePattern',
213 | value: function updatePattern(event) {
214 | var channelNum = parseInt(event.currentTarget.dataset.channel, 10);
215 | var stepNum = parseInt(event.currentTarget.dataset.stepindx, 10);
216 | var cpattern = this.state.currentPattern;
217 | if (cpattern[channelNum][stepNum]) {
218 | cpattern[channelNum][stepNum] = null;
219 | var colpattemp = this.columnPattern[stepNum].slice();
220 | var target = colpattemp.indexOf(this.sampleOrder[channelNum]);
221 | colpattemp.splice(target, 1);
222 | this.columnPattern[stepNum] = colpattemp;
223 | this.setState({ currentPattern: cpattern });
224 | } else {
225 | var newSamp = this.sampleOrder[channelNum];
226 | this.columnPattern[stepNum].push(newSamp);
227 | cpattern[channelNum][stepNum] = true;
228 | this.setState({ currentPattern: cpattern });
229 | }
230 | this.setState({ currentPattern: cpattern });
231 | }
232 | }, {
233 | key: 'abswitch',
234 | value: function abswitch() {
235 | this.setState({ bside: !this.state.bside });
236 | }
237 | }, {
238 | key: 'changeVolume',
239 | value: function changeVolume(e, value) {
240 | this.setState({ volume: value });
241 | if (value < -40) {
242 | value = -100;
243 | }
244 | _tone2.default.Master.volume.value = value;
245 | }
246 | }, {
247 | key: 'render',
248 | value: function render() {
249 | function makeSeqRow(v, i) {
250 | var pattern = void 0;
251 | if (this.state.bside) {
252 | pattern = v.slice(16);
253 | } else {
254 | pattern = v.slice(0, 16);
255 | }
256 | return _react2.default.createElement(_channel_row2.default, {
257 | bside: this.state.bside,
258 | key: i + 'row',
259 | channelNum: i,
260 | updateSeq: this.updatePattern,
261 | channel: pattern
262 | });
263 | }
264 |
265 | return _react2.default.createElement(
266 | 'div',
267 | { className: 'rackcabinet' },
268 | _react2.default.createElement(
269 | 'div',
270 | { className: 'rack' },
271 | _react2.default.createElement(
272 | 'div',
273 | { className: 'drumrack' },
274 | _react2.default.createElement(_screws2.default, null),
275 | _react2.default.createElement(_progress_bar2.default, { prog: this.state.position }),
276 | this.state.currentPattern.map(makeSeqRow, this),
277 | _react2.default.createElement(_playbar2.default, {
278 | bpm_num: this.state.bpm,
279 | toggle_f: this.abswitch,
280 | tempo_f: this.changeTempo,
281 | playbutton_f: this.startStop
282 | }),
283 | _react2.default.createElement(_screws2.default, null)
284 | )
285 | )
286 | );
287 | }
288 | }]);
289 |
290 | return drumMachine;
291 | }(_react.Component);
292 |
293 | exports.default = drumMachine;
294 |
295 | /***/ },
296 |
297 | /***/ 83:
298 | /***/ function(module, exports) {
299 |
300 | // removed by extract-text-webpack-plugin
301 |
302 | /***/ },
303 |
304 | /***/ 84:
305 | /***/ function(module, exports, __webpack_require__) {
306 |
307 | "use strict";
308 |
309 |
310 | Object.defineProperty(exports, "__esModule", {
311 | value: true
312 | });
313 | var nullTrack = exports.nullTrack = [[true, null, null, null, null, null, null, true, true, null, true, null, true, null, null, true, true, null, null, null, null, null, null, null, true, null, null, null, null, null, null, true], [null, null, null, null, null, null, null, null, null, null, true, true, null, null, null, null, null, null, null, null, null, null, true, true, null, true, null, true, null, true, null, null], [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null], [true, null, null, true, null, true, null, null, null, null, null, null, null, null, null, null, true, null, null, true, null, null, true, null, null, null, true, null, null, true, null, null], [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, true, null, true, null], [true, null, true, true, true, null, true, null, true, null, true, null, true, null, true, true, true, null, true, null, true, null, true, null, true, true, true, null, true, null, true, true], [null, null, null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null, true, null, null, null, true, null, null, null, true, null, null, true, null, null], [null, null, true, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null, null, null]];
314 |
315 | /***/ },
316 |
317 | /***/ 85:
318 | /***/ function(module, exports, __webpack_require__) {
319 |
320 | "use strict";
321 |
322 |
323 | Object.defineProperty(exports, "__esModule", {
324 | value: true
325 | });
326 | var demoTrack = exports.demoTrack = [[true, null, null, null, null, null, null, true, true, null, true, null, true, null, null, true, true, null, null, null, null, null, null, null, true, null, null, null, null, null, null, true], [null, null, null, null, null, null, null, null, null, null, true, true, null, null, null, null, null, null, null, null, null, null, true, true, null, true, null, true, null, true, null, null], [null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null], [true, null, null, true, null, null, true, null, null, null, null, null, null, null, null, null, true, null, null, true, null, null, true, null, null, null, true, null, null, true, null, null], [null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, true, null, true, null], [true, null, true, true, true, null, true, null, true, null, true, null, true, null, true, true, true, null, true, null, true, null, true, null, true, true, true, null, true, null, true, true], [null, null, null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null, true, null, null, null, true, null, null, null, true, null, null, true, null, null], [null, null, true, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, true, null, null, null, null, null, null, null, null, null, null, null, null, null]];
327 |
328 | /***/ },
329 |
330 | /***/ 86:
331 | /***/ function(module, exports, __webpack_require__) {
332 |
333 | "use strict";
334 |
335 |
336 | Object.defineProperty(exports, "__esModule", {
337 | value: true
338 | });
339 | exports.default = {
340 | '0:0:0': 0,
341 | '0:0:1': 1,
342 | '0:0:2': 2,
343 | '0:0:3': 3,
344 | '0:1:0': 4,
345 | '0:1:1': 5,
346 | '0:1:2': 6,
347 | '0:1:3': 7,
348 | '0:2:0': 8,
349 | '0:2:1': 9,
350 | '0:2:2': 10,
351 | '0:2:3': 11,
352 | '0:3:0': 12,
353 | '0:3:1': 13,
354 | '0:3:2': 14,
355 | '0:3:3': 15,
356 | '1:0:0': 0,
357 | '1:0:1': 1,
358 | '1:0:2': 2,
359 | '1:0:3': 3,
360 | '1:1:0': 4,
361 | '1:1:1': 5,
362 | '1:1:2': 6,
363 | '1:1:3': 7,
364 | '1:2:0': 8,
365 | '1:2:1': 9,
366 | '1:2:2': 10,
367 | '1:2:3': 11,
368 | '1:3:0': 12,
369 | '1:3:1': 13,
370 | '1:3:2': 14,
371 | '1:3:3': 15
372 | };
373 |
374 | /***/ },
375 |
376 | /***/ 87:
377 | /***/ function(module, exports, __webpack_require__) {
378 |
379 | "use strict";
380 |
381 |
382 | Object.defineProperty(exports, "__esModule", {
383 | value: true
384 | });
385 |
386 | var _react = __webpack_require__(11);
387 |
388 | var _react2 = _interopRequireDefault(_react);
389 |
390 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
391 |
392 | var channelRow = function channelRow(props) {
393 | function makeRow(v, i) {
394 | var channelClasses = v ? 'lighton' : 'lightoff';
395 | return _react2.default.createElement(
396 | 'div',
397 | {
398 | className: 'stepbutton',
399 | 'data-channel': props.channelNum,
400 | 'data-stepindx': props.bside ? i + 16 : i,
401 | onClick: props.updateSeq,
402 | key: 'c' + v + 's' + i
403 | },
404 | _react2.default.createElement('div', { className: channelClasses })
405 | );
406 | }
407 |
408 | return _react2.default.createElement(
409 | 'div',
410 | { className: 'sequencerrow' },
411 | props.channel.map(makeRow, undefined)
412 | );
413 | };
414 |
415 | channelRow.propTypes = {
416 | channelNum: _react.PropTypes.number.isRequired,
417 | bside: _react.PropTypes.bool.isRequired,
418 | updateSeq: _react.PropTypes.func.isRequired,
419 | channel: _react.PropTypes.array.isRequired
420 | };
421 |
422 | exports.default = channelRow;
423 |
424 | /***/ },
425 |
426 | /***/ 88:
427 | /***/ function(module, exports, __webpack_require__) {
428 |
429 | "use strict";
430 |
431 |
432 | Object.defineProperty(exports, "__esModule", {
433 | value: true
434 | });
435 |
436 | var _react = __webpack_require__(11);
437 |
438 | var _react2 = _interopRequireDefault(_react);
439 |
440 | var _toggle = __webpack_require__(91);
441 |
442 | var _toggle2 = _interopRequireDefault(_toggle);
443 |
444 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
445 |
446 | var playBar = function playBar(props) {
447 | return _react2.default.createElement(
448 | 'div',
449 | { className: 'drumrackbar' },
450 | _react2.default.createElement(
451 | 'div',
452 | { className: 'drumracklabel' },
453 | 'SEQUENCE'
454 | ),
455 | _react2.default.createElement(_toggle2.default, { abfunc: props.toggle_f }),
456 | _react2.default.createElement(
457 | 'div',
458 | { className: 'bpmplaybar' },
459 | _react2.default.createElement('input', { type: 'number', className: 'tempolabel', onChange: props.tempo_f, value: props.bpm_num })
460 | ),
461 | _react2.default.createElement(
462 | 'div',
463 | { className: 'playstopbutton', onClick: props.playbutton_f },
464 | _react2.default.createElement('i', { className: 'fa fa-play fa-2x', 'aria-hidden': 'true' }),
465 | _react2.default.createElement(
466 | 'div',
467 | { className: 'slash' },
468 | '/'
469 | ),
470 | _react2.default.createElement('i', { className: 'fa fa-stop fa-2x', 'aria-hidden': 'true' })
471 | )
472 | );
473 | };
474 |
475 | playBar.propTypes = {
476 | bpm_num: _react.PropTypes.number.isRequired,
477 | toggle_f: _react.PropTypes.func.isRequired,
478 | tempo_f: _react.PropTypes.func.isRequired,
479 | playbutton_f: _react.PropTypes.func.isRequired
480 | };
481 |
482 | exports.default = playBar;
483 |
484 | /***/ },
485 |
486 | /***/ 89:
487 | /***/ function(module, exports, __webpack_require__) {
488 |
489 | "use strict";
490 |
491 |
492 | Object.defineProperty(exports, "__esModule", {
493 | value: true
494 | });
495 |
496 | var _react = __webpack_require__(11);
497 |
498 | var _react2 = _interopRequireDefault(_react);
499 |
500 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
501 |
502 | var progressBar = function progressBar(props) {
503 | var temp = Array(16).fill(1);
504 | var temp2 = temp.map(function (v, i) {
505 | if (i === props.prog) {
506 | return _react2.default.createElement("div", {
507 | className: "progresslighton",
508 | key: v + "prog" + i
509 | });
510 | }
511 | return _react2.default.createElement("div", { className: "progresslight", key: v + "prog" + i });
512 | });
513 | return _react2.default.createElement(
514 | "div",
515 | { className: "progressbar" },
516 | temp2
517 | );
518 | };
519 |
520 | progressBar.propTypes = {
521 | prog: _react.PropTypes.number.isRequired
522 | };
523 |
524 | exports.default = progressBar;
525 |
526 | /***/ },
527 |
528 | /***/ 90:
529 | /***/ function(module, exports, __webpack_require__) {
530 |
531 | "use strict";
532 |
533 |
534 | Object.defineProperty(exports, "__esModule", {
535 | value: true
536 | });
537 |
538 | var _react = __webpack_require__(11);
539 |
540 | var _react2 = _interopRequireDefault(_react);
541 |
542 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
543 |
544 | exports.default = function () {
545 | return _react2.default.createElement(
546 | "div",
547 | { className: "screwplate" },
548 | _react2.default.createElement("div", { className: "screw" }),
549 | _react2.default.createElement("div", { className: "screw" })
550 | );
551 | };
552 |
553 | /***/ },
554 |
555 | /***/ 91:
556 | /***/ function(module, exports, __webpack_require__) {
557 |
558 | "use strict";
559 |
560 |
561 | Object.defineProperty(exports, "__esModule", {
562 | value: true
563 | });
564 |
565 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
566 |
567 | var _react = __webpack_require__(11);
568 |
569 | var _react2 = _interopRequireDefault(_react);
570 |
571 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
572 |
573 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
574 |
575 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
576 |
577 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
578 |
579 | var Toggle = function (_Component) {
580 | _inherits(Toggle, _Component);
581 |
582 | function Toggle(props) {
583 | _classCallCheck(this, Toggle);
584 |
585 | var _this = _possibleConstructorReturn(this, (Toggle.__proto__ || Object.getPrototypeOf(Toggle)).call(this, props));
586 |
587 | _this.state = {
588 | toggled: false
589 | };
590 | _this.handleChange = _this.handleChange.bind(_this);
591 | return _this;
592 | }
593 |
594 | _createClass(Toggle, [{
595 | key: 'handleChange',
596 | value: function handleChange() {
597 | this.props.abfunc();
598 | this.setState({ toggled: !this.state.toggled });
599 | }
600 | }, {
601 | key: 'render',
602 | value: function render() {
603 | var toggleClasses = 'togglebox';
604 | if (this.state.toggled) {
605 | toggleClasses += ' toggled';
606 | }
607 |
608 | return _react2.default.createElement(
609 | 'div',
610 | {
611 | className: toggleClasses,
612 | onClick: this.handleChange
613 | },
614 | _react2.default.createElement(
615 | 'div',
616 | { className: 'lettera' },
617 | 'A'
618 | ),
619 | _react2.default.createElement(
620 | 'div',
621 | { className: 'toggle-slider' },
622 | _react2.default.createElement('div', { className: 'toggle-slider-button' })
623 | ),
624 | _react2.default.createElement(
625 | 'div',
626 | { className: 'letterb' },
627 | 'B'
628 | )
629 | );
630 | }
631 | }]);
632 |
633 | return Toggle;
634 | }(_react.Component);
635 |
636 | Toggle.propTypes = {
637 | abfunc: _react.PropTypes.func.isRequired
638 | };
639 |
640 | exports.default = Toggle;
641 |
642 | /***/ }
643 |
644 | },[188]);
--------------------------------------------------------------------------------