<html>
<head>
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="//fb.me/react-with-addons-0.14.3.js"></script>
<script src="//fb.me/react-dom-0.14.3.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body class="container">
<div id="btn-group"></div>
<div id="react"></div>
</body>
</html>
body {
padding: 10px 0 0 10px;
background-color: lightgray;
font-size: 11px;
font-weight: bold;
}
.row {
width: 700px;
}
.inline-center {
text-align: center;
}
.col-md-1 {
margin-bottom: 0;
width: 30px;
display: inline-block;
}
var CommonMixins = {
columns: 21,
rows: 21,
rgba: 255,
create2DArray: function(num) {
var obj = [];
for (var i = 0; i < num; i++) {
obj[i] = [];
}
return obj;
},
getRandomNumber: function(num) {
return Math.floor((Math.random() * num) + 0);
}
};
var Cell = React.createClass({
mixins: [CommonMixins],
getInitialState: function() {
return {
rndX: 0,
rndY: 0,
rgba1: this.create2DArray(this.columns),
rgba2: this.create2DArray(this.columns),
rgba3: this.create2DArray(this.columns),
cells: this.create2DArray(this.columns)
}
},
render: function() {
var x = this.props.x;
var y = this.props.y;
var rndX = this.getRandomNumber(this.columns);
var rndY = this.getRandomNumber(this.rows);
this.state.cells[rndX][rndY] = this.props.values.rndNum;
this.state.rgba1[rndX][rndY] = this.props.values.rgba1Val;
this.state.rgba2[rndX][rndY] = this.props.values.rgba2Val;
this.state.rgba3[rndX][rndY] = this.props.values.rgba3Val;
var style = {
backgroundColor: "rgba(" + this.state.rgba1[x][y] + "," + this.state.rgba2[x][y] + "," + this.state.rgba3[x][y] + "," + 1 + ")"
};
return (
<div className="col-md-1 thumbnail inline-center" style={style}>
<div>{this.state.cells[x][y]}</div>
</div>
)
}
});
var Column = React.createClass({
shouldComponentUpdate: function(nextProps, nextState) {
return (this.props.columns !== nextProps.columns || this.props.values !== nextProps.values);
},
render: function() {
var column = [];
for (var i = 0; i < this.props.columns; i++) {
column.push(<Cell x={i} y={this.props.id} key={i} values={this.props.values} />);
}
return (<div className="row">{column}</div>)
}
});
var Row = React.createClass({
shouldComponentUpdate: function(nextProps, nextState) {
return (this.props.columns !== nextProps.columns || this.props.values !== nextProps.values);
},
render: function() {
var row = [];
for (var i = 0; i < this.props.rows; i++) {
row.push(<Column id={i} key={i} columns={this.props.columns} values={this.props.values} />);
}
return (<div>{row}</div>)
}
});
var Grid = React.createClass({
shouldComponentUpdate: function(nextProps, nextState) {
return (this.props.rows !== nextProps.rows || this.props.columns !== nextProps.columns || this.props.values !== nextProps.values);
},
render: function() {
return (<div><Row rows={this.props.rows} columns={this.props.columns} values={this.props.values} /></div>)
}
});
var Buttons = React.createClass({
shouldComponentUpdate: function(nextProps, nextState) {
return (this.props.isInterval !== nextProps.isInterval || this.props.start !== nextProps.start || this.props.stop !== nextProps.stop);
},
render: function() {
console.log(this.props.isInterval);
return (
<div>
{!this.props.isInterval
? <button className="btn btn-primary" onClick={this.props.start}>Start</button>
: <button className="btn btn-danger" onClick={this.props.stop}>Stop</button>
}
</div>
)
}
});
var GridMixins = {
getInitialState: function() {
return {
interval: {},
isInterval: false,
values: {}
}
},
randomizeCells: function() {
this.setState({
isInterval: true,
values: {
rndNum: this.getRandomNumber(this.rgba),
rgba1Val: this.getRandomNumber(this.rgba),
rgba2Val: this.getRandomNumber(this.rgba),
rgba3Val: this.getRandomNumber(this.rgba)
}
});
},
startTimer: function() {
console.log("Starting timer...");
this.state.interval = setInterval(this.randomizeCells, 0);
},
stopTimer: function() {
console.log("Stopping timer...");
clearInterval(this.state.interval);
this.setState({
isInterval: false
});
},
shouldComponentUpdate: function(nextProps, nextState) {
var values = (this.state.values.rndNum !== nextState.values.rndNum ||
this.state.values.rndNum !== nextState.values.rndNum ||
this.state.values.rgba1Val !== nextState.values.rgba1Val ||
this.state.values.rgba2Val !== nextState.values.rgba2Val ||
this.state.values.rgba3Val !== nextState.values.rgba3Val ||
this.state.isInterval !== nextState.isInterval);
return values;
}
};
var GridWrapper1 = React.createClass({
mixins: [CommonMixins, GridMixins],
render: function() {
return (
<div>
<Buttons start={this.startTimer} stop={this.stopTimer} isInterval={this.state.isInterval} /><br/>
<div className="grid"><Grid columns={this.columns} rows={this.rows} values={this.state.values} /></div>
</div>
)
}
});
ReactDOM.render(
<GridWrapper1 />,
document.body
);
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |