//image sequence functions
//preload array
/**
* 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, percentage) {
// 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 * percentage)
requestAnimationFrame(roll);
else
resolve(i);
}
roll();
})
}
//combine preload and play into one
function preloadAndPlay(ID, actor, event, percentage) {
var preload = preloadImages('/static/videos/' + actor + '/Clip_' + event + '/', 'png', 1);
preload.then(function (value) {
//console.log('starting play');
//canvas html5 object with ID
var canvas = document.getElementById(ID);
play(canvas, value, 30, 960, 540, percentage) // ~30fps
.then(function (frame) {
console.log('roll finished after ' + frame + ' frames.')
})
});
}
$.when(preloadAndPlay('myImage', actor, event, percentage)).done(function(){
$('.data').click(function () {
if ($(this).is(':checked')) {
$(this).removeClass('hidden');
$(that).addClass('hidden');
}
that = this;
});
$('.data').change(function () {
if (('input[name=b]:checked').length) {
$('#trial_next').prop('disabled', false);
cbChecked = document.querySelector('[name="b"]:checked').value;
debug(cbChecked);
}
});
});
I would like the .change and .click jquery to be only enabled after preloadAndPlay javascript function is COMPLETELY done executing. Jquery is are suppose to be allow radio buttons that can be selected. preloadAndPlay is a function that loads a series of images then displays them with html5 canvas so it seems like a video/animation. See above for the preloadAndPlay function that uses promise and recursion. The code works it's just I don't want people to make selection before the video ends. Above is the code I tried.