Skip to content

Instantly share code, notes, and snippets.

@T4rk1n
Last active July 21, 2017 04:48
Show Gist options
  • Save T4rk1n/e2fa86798e073ecde102666c42ebc146 to your computer and use it in GitHub Desktop.
Save T4rk1n/e2fa86798e073ecde102666c42ebc146 to your computer and use it in GitHub Desktop.
Image Roller
/**
* Preload images in a directory.
* @param {string} baseurl
* @param {string} extension
* @return {Promise} resolve an Array<Image>.
*/
function preloadImages(baseurl, extension, starter) {
return new Promise(function(res) {
var i = starter;
var images = [];
// Inner promise handler
var handler = function(resolve, reject) {
var img = new Image;
var source = baseurl + i + '.' + extension;
img.onload = function() {
i++;
resolve(img);
}
img.onerror = function() {
reject('Rejected after '+ i + 'frames.');
}
img.src = source;
}
// Once you catch the inner promise you resolve the outer one.
var _catch = function() { res(images) }
var operate = function(value) {
if (value) images.push(value);
// Inner recursive promises chain.
// Stop with the catch resolving the outer promise.
new Promise(handler).then(operate).catch(_catch);
}
operate();
})
}
/**
* Draw an Array of images on a canvas.
* @param {Canvas} canvas
* @param {Array<Image>} imagelist
* @param {number} refreshRate
*/
function play(canvas, imagelist, refreshRate, frameWidth, frameHeight) {
// Since we're using promises, let's promisify the animation too.
return new Promise(function(resolve) {
// May need to adjust the framerate
// requestAnimationFrame is about 60/120 fps depending on the browser
// and the refresh rate of the display devices.
var ctx = canvas.getContext('2d');
var ts, i = 0, delay = 1000 / refreshRate;
var roll = function(timestamp) {
if (!ts || timestamp - ts >= delay) {
// Since the image was prefetched you need to specify the rect.
ctx.drawImage(imagelist[i], 0, 0, frameWidth, frameHeight);
i++;
ts = timestamp;
}
if (i < imagelist.length)
requestAnimationFrame(roll);
else
resolve(i);
}
roll();
})
}
var preload = preloadImages('/static/videos/examples/testvid/', 'png', 1);
preload.then(function(value) {
console.log('starting play');
var canvas = document.getElementById("canvas");
play(canvas, value, 24, 720, 400) // ~480p 24fps
.then(function(frame){
console.log('roll finished after ' + frame + ' frames.')
})
});
<html>
<head>
</head>
<body>
<canvas id="canvas" width="720" height="400"></canvas>
<script src="imageroller.js"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment