<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<canvas width=600 height=400 id='cv'>
</canvas>
</body>
</html>
var arrows = [];
var gravity = 0.82;
var friction = 0.003;
var groundY = 300;
var towerHeight = 100;
var arrowCount = 5;
function Arrow(x,y,length, speed, angle) {
this.x=x;
this.y = y;
this.length = length;
this.speedX = 0;
this.speedY = 0;
this.moving = true;
this.launch( speed, angle);
}
Arrow.prototype.draw = function(ctx) {
ctx.beginPath();
ctx.moveTo(this.x, this.y);
var y= this.y+ this.length*this.speedY/this.speedNorm ;
ctx.lineTo(this.x+ this.length*this.speedX/this.speedNorm,
y);
if (y>=groundY) {
this.moving = false;
}
ctx.strokeStyle = '#F00';
ctx.stroke();
}
Arrow.prototype.launch=function (initialSpeed, angle) {
this.speedX = initialSpeed * Math.cos(angle);
this.speedY = initialSpeed * Math.sin(angle);
this.speedNorm = Math.sqrt(sq(this.speedX)+sq(this.speedY));
}
function randArrow() {
var x = 60 + 10*(Math.random()-0.5);
var y = groundY - 80 - 20*Math.random();
var speed = 22 + 4*Math.random();
var angle = -Math.PI*(0.15+0.125*Math.random());
var arr=new Arrow(x,y, 20, speed, angle);
return arr;
}
function updateArrows(delta) {
var i=0, a=null;
for(i=0;i<arrows.length;i++){
a = this.arrows[i];
if (!a.moving) continue;
a.x += delta*a.speedX;
a.y += delta*a.speedY;
a.speedY += delta*this.gravity - friction * a.speedNorm*sign(a.speedY);
a.speedNorm = Math.sqrt(sq(a.speedX)+sq(a.speedY));
a.speedX -= friction*a.speedNorm *sign(a.speedX);// friction*a.speedX ; // if you
}
}
function drawArrows(ctx) {
var i=0, a=null;
for(i=0;i<arrows.length;i++){
arrows[i].draw(ctx);
}
}
function sq(x) { return x*x ; }
function sign(x) { return x>=0?1:-1}
var cv=document.getElementById('cv');
var ctx = cv.getContext('2d');
for (var i=0; i<arrowCount; i++) {
arrows.push(randArrow());
}
function animate() {
requestAnimationFrame(animate);
ctx.clearRect(0,0,cv.width, cv.height);
drawArrows(ctx);
ctx.fillStyle='hsl(240,80%,80%)';
ctx.fillRect(10, groundY-towerHeight, 50, towerHeight );
ctx.fillStyle='hsl(80,80%,80%)';
ctx.fillRect(0, groundY, cv.width, cv.height-groundY);
updateArrows(0.16);
}
animate();
function addArrow() {
arrows.push(randArrow());
setTimeout(addArrow, Math.floor(50+Math.random()*30));
}
addArrow();
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. |