<html>
<head>
<meta name="description" content="Draws a content pipeline graph">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
</body>
</html>
/* jshint esnext: true */
var Rect = class
{
constructor(opt) {
if (opt.w || opt.width) {this.w = opt.w || opt.width;}
else if (opt.left && opt.right) {this.w = opt.right - opt.left;}
else {opt.w = 0.0;}
if (opt.x || opt.left) {this.x = opt.x || opt.left;}
else if (opt.center) {this.x = opt.center - this.w/2;}
else if (opt.right) {this.x = opt.right - this.w;}
else {opt.x = 0.0;}
if (opt.h || opt.height) {this.h = opt.h || opt.height;}
else if (opt.top && opt.bottom) {this.h = opt.bottom - opt.top;}
else {opt.h = 0.0;}
if (opt.y || opt.top) {this.y = opt.y || opt.top;}
else if (opt.middle) {this.y = opt.middle - this.h/2;}
else if (opt.bottom) {this.y = opt.bottom - this.h;}
else {opt.y = 0.0;}
}
get left() {return this.x;}
get center() {return this.x + this.w/2;}
get right() {return this.x + this.w;}
get top() {return this.y;}
get middle() {return this.y + this.h/2;}
get bottom() {return this.y + this.h;}
get topLeft() {return new Rect({x: this.left, y: this.top});}
get topCenter() {return new Rect({x: this.center, y: this.top});}
get topRight() {return new Rect({x: this.right, y: this.top});}
get middleLeft() {return new Rect({x: this.left, y: this.middle});}
get middleCenter() {return new Rect({x: this.center, y: this.middle});}
get middleRight() {return new Rect({x: this.right, y: this.middle});}
get bottomLeft() {return new Rect({x: this.left, y: this.bottom});}
get bottomCenter() {return new Rect({x: this.center, y: this.bottom});}
get bottomRight() {return new Rect({x: this.right, y: this.bottom});}
offset(x,y) {return new Rect({x: this.x+x, y: this.y+y, w: this.w, h: this.h});}
outset(s) {return new Rect({x: this.x-s, y: this.y-s, w: this.w+2*s, h: this.h+2*s});}
static union() {
var left,right,top,bottom;
for (var i=0; i<arguments.length; ++i) {
var r = arguments[i];
left = Math.min(left || r.left, r.left);
right = Math.max(right || r.right, r.right);
top = Math.min(top || r.top, r.top);
bottom = Math.max(bottom || r.bottom, r.bottom);
}
return new Rect({left:left, top:top, right:right, bottom:bottom});
}
};
var draw = {
textbox: function(ctx, text, r) {
ctx.save();
ctx.fillStyle = "#eee";
ctx.fillRect(r.x,r.y,r.w,r.h);
ctx.fillStyle = "#000";
ctx.strokeRect(r.x,r.y,r.w,r.h);
ctx.textBaseline = "middle";
ctx.textAlign = "center";
ctx.fillText(text, r.center, r.middle);
ctx.restore();
},
arrow: function(ctx, p1, p2, doubleArrow) {
ctx.save();
var w = 10;
var h = 20;
ctx.beginPath();
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p2.x, p2.y);
var len = Math.sqrt((p2.x-p1.x)*(p2.x-p1.x) + (p2.y-p1.y)*(p2.y-p1.y));
var dx = (p2.x-p1.x)/len;
var dy = (p2.y-p1.y)/len;
ctx.lineTo(p2.x - dx*h - dy*w, p2.y - dy*h + dx*w);
ctx.moveTo(p2.x, p2.y);
ctx.lineTo(p2.x - dx*h + dy*w, p2.y - dy*h - dx*w);
if (doubleArrow) {
ctx.moveTo(p1.x,p1.y);
ctx.lineTo(p1.x + dx*h - dy*w, p1.y + dy*h + dx*w);
ctx.moveTo(p1.x, p1.y);
ctx.lineTo(p1.x + dx*h + dy*w, p1.y + dy*h - dx*w);
}
ctx.stroke();
ctx.restore();
return new Rect({left: p1.x, top: p1.y, right: p2.x, bottom: p2.y});
}
};
function drawFrame(opt)
{
var ctx = opt.ctx;
ctx.save();
var r = opt.r;
r = r.outset(25);
r.y -= 25;
r.h += 25;
ctx.fillStyle = opt.color || "#ff9";
ctx.strokeStyle = "#333";
ctx.setLineDash([5,5]);
ctx.strokeRect(r.x, r.y, r.w, r.h);
ctx.fillRect(r.x, r.y, r.w, r.h);
ctx.fillStyle = "#000";
ctx.textAlign = "left";
ctx.textBaseline = "top";
ctx.fillText(opt.text || "Frame", r.left+10, r.top+10);
ctx.restore();
}
function clear(ctx)
{
ctx.save();
ctx.fillStyle = "#fff";
ctx.fillRect(0,0,10000,10000);
ctx.restore();
}
function drawPipeline(ctx)
{
clear(ctx);
var disk = new Rect({x: 50, y: 80, w: 200, h:50});
var trans = disk.offset(0, 200);
var user = trans.offset(0, 150);
var compiled = disk.offset(350, 0);
var loaded = compiled.offset(0, 200);
var instance = loaded.offset(0, 150);
ctx.font = "bold 14px Arial";
drawFrame({ctx: ctx, r:Rect.union(trans,user), text: "EDITOR", color: "#fcf"});
drawFrame({ctx: ctx, r:Rect.union(disk,compiled), text: "DISK", color: "#cff"});
drawFrame({ctx: ctx, r:Rect.union(loaded,instance), text: "RUNTIME", color: "#ffc"});
ctx.font = "18px Arial";
draw.textbox(ctx, "Resource (disk)", disk);
draw.textbox(ctx, "Resource (transient)", trans);
draw.textbox(ctx, "User", user);
draw.textbox(ctx, "Resource (compiled)", compiled);
draw.textbox(ctx, "Resource (loaded)", loaded);
draw.textbox(ctx, "Instance", instance);
var modify = draw.arrow(ctx, user.topCenter, trans.bottomCenter);
ctx.fillText("Modify", modify.center + 20, modify.middle);
var save = draw.arrow(ctx, trans.topCenter, disk.bottomCenter);
ctx.fillText("Save", save.center + 20, save.middle);
var compile = draw.arrow(ctx, disk.middleRight, compiled.middleLeft);
ctx.textAlign = "center";
ctx.fillText("Compile", compile.center, compile.middle - 20);
var load = draw.arrow(ctx, compiled.bottomCenter, loaded.topCenter);
ctx.textAlign = "left";
ctx.fillText("Load", load.center + 20, load.middle);
var spawn = draw.arrow(ctx, loaded.bottomCenter, instance.topCenter);
ctx.fillText("Spawn", spawn.center + 20, spawn.middle);
}
function render()
{
var body = document.getElementsByTagName("body")[0];
while (body.hasChildNodes()) {
body.removeChild(body.lastChild);
}
body.style.backgroundColor = "#ccc";
{
var canvas = document.createElement("canvas");
canvas.width = 650;
canvas.height = 530;
var ctx = canvas.getContext("2d");
drawPipeline(ctx);
body.appendChild(canvas);
}
}
render();
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. |