<html>
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<input type="file" id="file" multiple><br>
<div id="progress"></div>
</body>
</html>
img {
margin-right: 10px;
}
#progress {
font-family: courier;
margin: 40px;
}
// noprotect
var width = 320;
function taskQueue(capacity) {
var running = 0;
var queue = [];
function release() {
if (queue.length) {
var task = queue.shift();
task(release);
} else {
running -= 1;
}
}
return function(task) {
if (running < capacity) {
running += 1;
task(release);
} else {
queue.push(task);
}
};
}
function protect(img) {
var ratio = img.width / img.height;
var maxSquare = 5000000; // ios max canvas square
var maxSize = 4096; // ie max canvas dimensions
var maxW = Math.floor(Math.sqrt(maxSquare * ratio));
var maxH = Math.floor(maxSquare / Math.sqrt(maxSquare * ratio));
if (maxW > maxSize) {
maxW = maxSize;
maxH = Math.round(maxW / ratio);
}
if (maxH > maxSize) {
maxH = maxSize;
maxW = Math.round(ratio * maxH);
}
if (img.width > maxW) {
var canvas = document.createElement('canvas');
canvas.width = maxW;
canvas.height = maxH;
canvas.getContext('2d').drawImage(img, 0, 0, maxW, maxH);
img.src = 'about:blank';
img.width = 1;
img.height = 1;
img = canvas;
}
return img;
}
function resize(img, w, h) {
var df = $.Deferred();
setTimeout(function(){
img = protect(img);
console.log(img.width, img.height);
var steps = Math.ceil(Math.log(img.width / w) / Math.LN2);
var sW = w * Math.pow(2, steps - 1);
var sH = h * Math.pow(2, steps - 1);
var x = 2;
function run() {
if ( ! (steps--)) {
df.resolve(img);
return;
}
setTimeout(function() {
console.log(sW, sH);
var canvas = document.createElement('canvas');
canvas.width = sW;
canvas.height = sH;
canvas.getContext('2d').drawImage(img, 0, 0, sW, sH);
img.src = 'about:blank';
img.width = 1;
img.height = 1;
img = canvas;
sW = Math.round(sW / x);
sH = Math.round(sH / x);
run();
}, 0);
}
run();
}, 0);
return df.promise();
}
function imageLoader(src) {
var df = $.Deferred();
var img = new Image();
img.onload = function() {
df.resolve(img);
};
img.onerror = function() {
df.reject(img);
};
img.src = src;
return df.promise();
}
var resizeQueue = taskQueue(1);
function resizeFile(file, width) {
var df = $.Deferred();
resizeQueue(function(release) {
df.always(release);
var op = imageLoader(URL.createObjectURL(file));
op.done(function(img) {
var height = Math.round(width * img.height / img.width);
resize(img, width, height).done(df.resolve);
});
op.fail(df.reject);
op.always(function(img) {
URL.revokeObjectURL(img.src);
});
});
return df.promise();
}
$('#file').on('change', function() {
$.each($('#file').prop('files'), function(i, file) {
resizeFile(file, width).done(function(canvas) {
$('body').append(
$("<p/>").append(canvas)
);
});
});
});
var progress = 0;
setInterval(function() {
$('#progress').text("|/-\\"[progress % 4]);
progress += 1;
}, 100);
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. |