如何提高图像交叉淡入淡出性能?

时间:2011-03-17 04:35:49

标签: javascript jquery animation performance

我希望能够对宽度设置为屏幕100%的大图像进行淡入淡出过渡。我有一个我想要完成的工作示例。但是,当我在各种浏览器和各种计算机上测试时,我无法在任何地方进行黄油平滑过渡。

请参阅有关jsFiddle的演示:http://jsfiddle.net/vrD2C/

请参阅Amazon S3:http://imagefader.s3.amazonaws.com/index.htm

我想知道如何提高性能。这是实际进行图像交换的功能:

function swapImage(oldImg, newImg) {
    newImg.css({
        "display": "block",
        "z-index": 2,
        "opacity": 0
    })
    .removeClass("shadow")
    .animate({ "opacity": 1 }, 500, function () {
        if (oldImg) {
            oldImg.hide();
        }
        newImg.addClass("shadow").css("z-index", 1);
    });
}

使用jQuery animate()来改变不透明度是一种不好的方法吗?

4 个答案:

答案 0 :(得分:3)

您可能希望研究CSS3 Transitions,因为浏览器可能比Javascript更好地优化它,直接在循环中设置属性。这似乎是一个非常好的开始:

http://robertnyman.com/2010/04/27/using-css3-transitions-to-create-rich-effects/

答案 1 :(得分:2)

我不确定这是否有助于优化您的性能,因为我目前在扩展机器上使用IE9,即使我将浏览器置于IE7或8文档模式,JavaScript也不会因您当前的代码而动摇。但是,您可以考虑对代码进行以下优化。

通过将所有照片放在隐藏的容器中来整理主照片阶段的内容,您可以给出“队列”或类似内容的ID,使DOM执行存储和排序您当前未显示的图像的工作为了你。这也将使浏览器在任何给定时间仅使用两个可见图像,从而减少了对堆叠上下文,定位等的考虑。

重写代码以使用事件触发器并将淡入处理绑定到事件,在当前转换完成后调用队列事件中的第一个图像。我发现这种方法比一些超时管理的脚本更适合循环动画。如何执行此操作的示例如下:

// Bind a custom event to each image called "transition"
$("#queue img").bind("transition", function() {
    $(this)
        // Hide the image
        .hide()

        // Move it to the visible stage
        .appendTo("#photos")

        // Delay the upcoming animation by the desired value
        .delay(2500)

        // Slowly fade the image in
        .fadeIn("slow", function() {

            // Animation callback
            $(this)

                // Add a shadow class to this image
                .addClass("shadow")

            // Select the replaced image
            .siblings("img")

                // Remove its shadow class
                .removeClass("shadow")

                // Move it to the back of the image queue container
                .appendTo("#queue");

            // Trigger the transition event on the next image in the queue
            $("#queue img:first").trigger("transition");

        });   
}).first().addClass("shadow").trigger("transition"); // Fire the initial event

在问题浏览器中尝试this working demo,如果效果不佳,请告诉我。

答案 2 :(得分:0)

我也有同样的问题。我刚刚预装了我的图像,转换再次变得平滑。

答案 3 :(得分:0)

重点是IE不符合W3C标准,但使用css的ctcherry +1是平滑过渡的最有效方式。

然后有javascript编码的解决方案,使用js直接(但需要一些努力来遵守W3C Vs浏览器),或者使用像JQuery或Mootools这样的库。

这是一个符合您需求的良好的JavaScript编码示例(See demo online)

var Fondu = function(classe_img){
this.classe_img = classe_img;
    this.courant = 0;
this.coeff = 100;
this.collection = this.getImages();
this.collection[0].style.zIndex = 100;
this.total = this.collection.length - 1;
this.encours = false;
}
Fondu.prototype.getImages = function(){
var tmp = [];
if(document.getElementsByClassName){
    tmp = document.getElementsByClassName(this.classe_img);
}
else{
    var i=0;
    while(document.getElementsByTagName('*')[i]){
        if(document.getElementsByTagName('*')[i].className.indexOf(this.classe_img) > -1){
            tmp.push(document.getElementsByTagName('*')[i]);
        }
        i++;
    }
}
var j=tmp.length;
while(j--){
    if(tmp[j].filters){
        tmp[j].style.width = tmp[j].style.width || tmp[j].offsetWidth+'px';
        tmp[j].style.filter = 'alpha(opacity=100)';
        tmp[j].opaque = tmp[j].filters[0];
        this.coeff = 1;
    }
    else{
        tmp[j].opaque = tmp[j].style;
    }
}
return tmp;
}
Fondu.prototype.change = function(sens){
if(this.encours){
    return false;
}
var prevObj = this.collection[this.courant];
this.encours = true;
if(sens){
    this.courant++;
    if(this.courant>this.total){
        this.courant = 0;
    }
}
else{
    this.courant--;
    if(this.courant<0){
        this.courant = this.total;
    }
}
var nextObj = this.collection[this.courant];
nextObj.style.zIndex = 50;
var tmpOp = 100;
var that = this;
var timer = setInterval(function(){
    if(tmpOp<0){
        clearInterval(timer);
        timer = null;
        prevObj.opaque.opacity = 0;
        nextObj.style.zIndex = 100;
        prevObj.style.zIndex = 0;
        prevObj.opaque.opacity = 100 / that.coeff;
        that.encours = false;
    }
    else{
        prevObj.opaque.opacity = tmpOp / that.coeff;
        tmpOp -= 5;
    }
}, 25);
}