【问题标题】:How to improve image cross-fade performance?如何提高图像淡入淡出性能?
【发布时间】:2011-03-17 04:35:48
【问题描述】:

我希望能够对宽度设置为屏幕 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() 来改变不透明度是一个不好的方法吗?

【问题讨论】:

    标签: javascript jquery animation performance


    【解决方案1】:

    您可能想研究 CSS3 过渡,因为浏览器可能能够比 Javascript 直接在循环中设置属性更好地优化它。这似乎是一个不错的开始:

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

    【讨论】:

    • CSS3 过渡最终解决了我的特殊需求。我在 iOS 设备上看到了巨大的性能提升,尤其是通过使用它们。
    • @jessegavin,您介意发布您的解决方案吗?我正在使用 jQuery 的 fadeOut 和 z-index 属性来循环浏览整页背景图像,但是当背景图像被拉伸时,我在 Safari 上的性能变慢了。
    【解决方案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,如果性能仍然很差,请告诉我。

    【讨论】:

      【解决方案3】:

      我也有同样的问题。我刚刚预加载了我的图像,过渡又变得平滑了。

      【讨论】:

      • 在我的情况下,预加载不是一个因素。出于这个问题的目的,我们假设所有图像都在幻灯片开始播放之前加载到内存中。我想知道如何确保交叉淡入淡出本身尽可能平滑。
      • 我想我不会认为这是可能的。你过去这样做过吗?
      • 我没有尝试过,因为我认为这个功能会更复杂一些。你可以试试看能否得到更流畅的动画
      【解决方案4】:

      关键是 IE 不符合 W3C,但 +1 与 ctcherry 因为使用 css 是平滑过渡的最有效方式。

      然后是 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);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-12-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多