使用链式 JavaScript Promise 淡化 out/in 图像
Fading out/in images using chained JavaScript Promises
我正在尝试创建一个非JQuery 图片幻灯片,其中图片根据计时器淡出 in/out。经过今天的大量研究,我相信 JavaScript 的 Promise 功能可以做到这一点,但它不太正确......
我的问题是淡入和淡出功能似乎同时发生,所以图像只是闪烁。我正在尝试调整使用 then()
链接函数的许多示例中的一些示例,但显然有些地方是错误的。
我的逻辑是:
- 在页面加载时显示初始图像(通过 CSS 规则)
- 淡出
- 更改背景图片URL
- 淡入
我的 online example is here,JavaScript 在这里:
// Background images to show
var arr_Images = [
'https://cdn.pixabay.com/photo/2015/08/24/12/53/banner-904884_960_720.jpg',
'https://cdn.pixabay.com/photo/2016/11/19/22/52/coding-1841550_960_720.jpg',
'https://cdn.pixabay.com/photo/2014/05/27/23/32/matrix-356024_960_720.jpg'
];
var cycleImage = document.getElementById("cycleImage");
// Preload images
for(x = 0; x < arr_Images.length; x++)
{
var img = new Image();
img.src = arr_Images[x];
}
function fadeOutPromise(element, nextBgImgUrl) {
console.log("Fading out");
return new Promise(function(resolve) {
var op = 1; // initial opacity
var timer1 = setInterval(function () {
if (op <= 0.1){
clearInterval(timer1);
element.style.display = 'none';
cycleImage.style.backgroundImage = "url('" + nextBgImgUrl + "')";
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.1;
}, 100);
resolve("Faded In");
});
}
function fadeInPromise(element) {
console.log("Fading in");
return new Promise(function(resolve) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer2 = setInterval(function () {
if (op >= 1){
clearInterval(timer2);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
resolve("Faded Out");
});
}
function slideShow() {
// Loop background image using array
var i = 0;
var delay = 3000;
// Loop
let imageLoopTimer = setTimeout(function tick() {
fadeOutPromise(cycleImage, arr_Images[i]).then(
fadeInPromise(cycleImage).then(function() {
i++;
if ( i >= arr_Images.length) { i = 0; }
imageLoopTimer = setTimeout(tick, delay);
})
);
}, delay);
}
slideShow();
有人可以先解释一下哪里出了问题,然后提供解决方案吗?
你快到了。问题是你如何兑现你的承诺。
您打算在淡入淡出功能中做的是:
- 创建承诺
- 以间隔
执行逻辑
- 解决承诺
但是你立即解决了这个承诺,而你应该在 fade 操作完成后解决你的承诺:
function fadeInPromise(element) {
console.log("Fading in");
return new Promise(function(resolve) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer2 = setInterval(function () {
if (op >= 1){
clearInterval(timer2);
resolve(): // Fade is done here
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
});
}
淡出也一样
闪烁的另一个提示
如果你想要平滑的效果,你不应该经常改变不透明度。在css中,已经有'transition'属性。所以你应该用转换做这样的事情:
- 显示不透明度为 1
的图像
- 将 opactiy 设置为 0
- 在 ms 之后,更改 url 并将不透明度设置为 1
setInterval()
是 运行 作为后台任务,因此 resolve()
将在 timer2
.
初始化后立即触发
- 它非常类似于 运行 一个
async
操作,但不是 awaiting
它。
- 或者使用 promises 就像调用一个
function
那个 returns 一个 Promise
,但是想在没有 .then()
回调的情况下访问数据
您需要在 if (op >= 1)
部分解决您的承诺,以便在 fadeIn/Out 发生后真正解决它。
检查 this snippet 以获取您的更新版本。 Promise 在 setInterval()
.
中解决
这里是它的相关 JavaScript 代码作为直接片段:
function fadeOutPromise(element, nextBgImgUrl) {
console.log("Fading out"+i);
return new Promise(function(resolve, reject) {
element.style.opacity = 0;
setTimeout(() => {
console.log("Fading out done"+i);
element.style.backgroundImage = "url('" + nextBgImgUrl + "')";
resolve();
}, 1000);
});
}
function fadeInPromise(element) {
console.log("Fading in"+i);
return new Promise(function(resolve, reject) {
element.style.opacity = 1;
setTimeout(resolve, 1000);
});
}
var i = 0;
var delay = 3000;
function slideShow() {
// Loop background image using array
// Loop
let imageLoopTimer = setTimeout(() => tick(), delay);
}
function tick() {
fadeOutPromise(cycleImage, arr_Images[i]).then(() =>
fadeInPromise(cycleImage).then(function() {
i++;
if ( i >= arr_Images.length) { i = 0; }
imageLoopTimer = setTimeout(() => tick(), delay);
})
);
}
编辑(使用过渡不透明度)
我有 edited the snippet,现在它可以与不透明度过渡一起使用。
我正在尝试创建一个非JQuery 图片幻灯片,其中图片根据计时器淡出 in/out。经过今天的大量研究,我相信 JavaScript 的 Promise 功能可以做到这一点,但它不太正确......
我的问题是淡入和淡出功能似乎同时发生,所以图像只是闪烁。我正在尝试调整使用 then()
链接函数的许多示例中的一些示例,但显然有些地方是错误的。
我的逻辑是:
- 在页面加载时显示初始图像(通过 CSS 规则)
- 淡出
- 更改背景图片URL
- 淡入
我的 online example is here,JavaScript 在这里:
// Background images to show
var arr_Images = [
'https://cdn.pixabay.com/photo/2015/08/24/12/53/banner-904884_960_720.jpg',
'https://cdn.pixabay.com/photo/2016/11/19/22/52/coding-1841550_960_720.jpg',
'https://cdn.pixabay.com/photo/2014/05/27/23/32/matrix-356024_960_720.jpg'
];
var cycleImage = document.getElementById("cycleImage");
// Preload images
for(x = 0; x < arr_Images.length; x++)
{
var img = new Image();
img.src = arr_Images[x];
}
function fadeOutPromise(element, nextBgImgUrl) {
console.log("Fading out");
return new Promise(function(resolve) {
var op = 1; // initial opacity
var timer1 = setInterval(function () {
if (op <= 0.1){
clearInterval(timer1);
element.style.display = 'none';
cycleImage.style.backgroundImage = "url('" + nextBgImgUrl + "')";
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op -= op * 0.1;
}, 100);
resolve("Faded In");
});
}
function fadeInPromise(element) {
console.log("Fading in");
return new Promise(function(resolve) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer2 = setInterval(function () {
if (op >= 1){
clearInterval(timer2);
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
resolve("Faded Out");
});
}
function slideShow() {
// Loop background image using array
var i = 0;
var delay = 3000;
// Loop
let imageLoopTimer = setTimeout(function tick() {
fadeOutPromise(cycleImage, arr_Images[i]).then(
fadeInPromise(cycleImage).then(function() {
i++;
if ( i >= arr_Images.length) { i = 0; }
imageLoopTimer = setTimeout(tick, delay);
})
);
}, delay);
}
slideShow();
有人可以先解释一下哪里出了问题,然后提供解决方案吗?
你快到了。问题是你如何兑现你的承诺。
您打算在淡入淡出功能中做的是:
- 创建承诺
- 以间隔
执行逻辑
- 解决承诺
但是你立即解决了这个承诺,而你应该在 fade 操作完成后解决你的承诺:
function fadeInPromise(element) {
console.log("Fading in");
return new Promise(function(resolve) {
var op = 0.1; // initial opacity
element.style.display = 'block';
var timer2 = setInterval(function () {
if (op >= 1){
clearInterval(timer2);
resolve(): // Fade is done here
}
element.style.opacity = op;
element.style.filter = 'alpha(opacity=' + op * 100 + ")";
op += op * 0.1;
}, 10);
});
}
淡出也一样
闪烁的另一个提示
如果你想要平滑的效果,你不应该经常改变不透明度。在css中,已经有'transition'属性。所以你应该用转换做这样的事情:
- 显示不透明度为 1
的图像
- 将 opactiy 设置为 0
- 在 ms 之后,更改 url 并将不透明度设置为 1
setInterval()
是 运行 作为后台任务,因此 resolve()
将在 timer2
.
- 它非常类似于 运行 一个
async
操作,但不是awaiting
它。 - 或者使用 promises 就像调用一个
function
那个 returns 一个Promise
,但是想在没有.then()
回调的情况下访问数据
您需要在 if (op >= 1)
部分解决您的承诺,以便在 fadeIn/Out 发生后真正解决它。
检查 this snippet 以获取您的更新版本。 Promise 在 setInterval()
.
这里是它的相关 JavaScript 代码作为直接片段:
function fadeOutPromise(element, nextBgImgUrl) {
console.log("Fading out"+i);
return new Promise(function(resolve, reject) {
element.style.opacity = 0;
setTimeout(() => {
console.log("Fading out done"+i);
element.style.backgroundImage = "url('" + nextBgImgUrl + "')";
resolve();
}, 1000);
});
}
function fadeInPromise(element) {
console.log("Fading in"+i);
return new Promise(function(resolve, reject) {
element.style.opacity = 1;
setTimeout(resolve, 1000);
});
}
var i = 0;
var delay = 3000;
function slideShow() {
// Loop background image using array
// Loop
let imageLoopTimer = setTimeout(() => tick(), delay);
}
function tick() {
fadeOutPromise(cycleImage, arr_Images[i]).then(() =>
fadeInPromise(cycleImage).then(function() {
i++;
if ( i >= arr_Images.length) { i = 0; }
imageLoopTimer = setTimeout(() => tick(), delay);
})
);
}
编辑(使用过渡不透明度)
我有 edited the snippet,现在它可以与不透明度过渡一起使用。