簡體   English   中英

使用鏈接的JavaScript承諾淡入/淡出圖像

[英]Fading out/in images using chained JavaScript Promises

我正在嘗試創建一個非JQuery圖像幻燈片,其中圖像基於計時器淡入/淡出。 經過大量研究后,我相信JavaScript的Promise功能可以做到這一點,但這並不完全正確...

我的問題是淡入和淡出功能似乎同時發生,因此圖像只是閃爍。 我正在嘗試改編許多使用then()鏈接函數的示例,但是顯然有些錯誤。

我的邏輯是:

  1. 在頁面加載時顯示初始圖像(通過CSS規則)
  2. 淡出
  3. 更改背景圖片網址
  4. 淡入

我的在線示例在此處 ,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();

有人可以先說明問題所在,然后提供解決方案嗎?

你快到了。 問題是您如何履行諾言。 您打算在淡入淡出功能中執行的操作是:
-創造承諾
-間隔執行邏輯
-兌現承諾

但是您可以立即解決承諾,而一旦淡入淡出操作完成,就應該解決承諾:

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之后,更改網址並將不透明度設置為1

setInterval()作為后台任務運行,因此將在timer2初始化后立即觸發resolve()

  • 它與運行async操作非常相似,但不awaiting它。
  • 或與promises一樣,就像調用一個返回Promisefunction ,但要訪問數據而沒有.then()回調

您需要在if (op >= 1)部分內解決您的諾言,以便在fadeIn / Out發生實際解決它。

查看此代碼段以獲取您的更新版本。 setInterval()內部解析了Promises。

以下是直接代碼段的相關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);               
        })
    );

}

編輯(具有過渡不透明度)

我已經編輯了代碼段 ,現在它可以與不透明度過渡一起使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM