Skip to content

Instantly share code, notes, and snippets.

@pongo
Last active August 18, 2022 08:15
Show Gist options
  • Select an option

  • Save pongo/2939935067cfd5ddff75 to your computer and use it in GitHub Desktop.

Select an option

Save pongo/2939935067cfd5ddff75 to your computer and use it in GitHub Desktop.
Пример реализации очереди
// 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 = canvas;
}
return img;
}
var resizeQueue = taskQueue(1); // Number of simultaneous tasks.
function resize(img, w, h) {
var df = $.Deferred();
resizeQueue(function(release) {
setTimeout(function(){
img = protect(img);
console.log(img.width, img.height);
var steps = Math.ceil(Math.log2(img.width / w));
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);
release();
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 = 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();
}
$('#file').on('change', function() {
var images = $.map($('#file').prop('files'), function(file) {
return imageLoader(URL.createObjectURL(file));
});
$.when.apply(null, images).done(function() {
$.each(arguments, function(i, img) {
var height = Math.round(width * img.height / img.width);
resize(img, width, height).done(function(canvas) {
$(img).attr({width: width, height: height});
$('body').append(
$("<p/>").append(
[canvas]
)
);
});
});
});
});
var progress = 0;
setInterval(function() {
$('#progress').text("|/-\\"[progress % 4]);
progress += 1;
}, 100);
// 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);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment