[英]Enable Jquery Only after Javascript recursive function is done executing
//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);
}
});
});
我希望仅在preloadAndPlay javascript函数完全完成执行后才能启用.change和.click jQuery。 假设jQuery是允许选择的单选按钮。 preloadAndPlay是一个函数,该函数加载一系列图像,然后使用html5画布显示它们,因此看起来像是视频/动画。 请参阅上面的有关使用promise和递归的preloadAndPlay函数。 该代码有效,只是我不希望人们在视频结束之前进行选择。 上面是我尝试的代码。
在Question的代码中有几个问题。 在preloadImages
函数中,传递给Promise
构造函数的函数参数名为res
,尽管在<img>
load
事件中在函数中调用了resolve()
,但在函数中未定义resolve
。 未调用handler
,未达到对未定义的resolve()
调用。 在Promise
构造函数中不需要operate
函数。 没有价值return
来自ED operate
,请参阅为什么在值。然后()链接到答应未定义? 。
您可以使用Promise.all()
来传递,其中链的迭代对象.then()
所有这些值,时应该叫Promise
传递的值被满足。
不确定play()
调用的预期效果是什么,也不确定那部分代码是否是原始查询的一部分。 调整后的代码片段可以为每个图像调用requestAnimationFrame
。
const baseurl = "https://lorempixel.com/50/50/"; const data = ["cats", "nature", "city"]; const canvas = document.querySelector("canvas"); function preloadImages(image) { return new Promise(function(resolve) { var img = new Image; var source = baseurl + image; img.onload = function() { resolve(img); } img.onerror = function() { reject('Rejected after ' + i + 'frames.'); } img.src = source; }) } 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(); }) } function preloadAndPlay(percentage) { var preload = Promise.all(data.map(preloadImages)) .then(function(images) { console.log("preloadImages complete, images:", images); images.forEach(function(img) { document.body.appendChild(img) }); return images }) .catch(function(err) { console.error(err); throw err; }); return preload.then(function(value) { console.log("preload complete, value:", value); return play(canvas, value, 30, 960, 540, percentage) // ~30fps .then(function(frame) { console.log('roll finished after ' + frame + ' frames.'); return "done"; }) }); } preloadAndPlay() .then(function(data) { console.log(data); }) .catch(function(err) { console.error(err) })
<canvas></canvas>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.