【问题标题】:Stop a gif animation onload, on mouseover start the activation停止加载 gif 动画,鼠标悬停开始激活
【发布时间】:2011-08-14 15:37:03
【问题描述】:

我有一个包含很多 GIF 的页面。

<img src="gif/1303552574110.1.gif" alt="" >
<img src="gif/1302919192204.gif" alt="" >
<img src="gif/1303642234740.gif" alt="" >
<img src="gif/1303822879528.gif" alt="" >
<img src="gif/1303825584512.gif" alt="" >

我在寻找什么

1 页面加载时 => 停止所有 gif 的动画

2 在鼠标悬停时 => 动画为那个 gif 启动

3 On mouseout => 该 gif 动画再次停止

我想这可以在 Jquery 中完成,但我不知道如何。

【问题讨论】:

标签: jquery gif


【解决方案1】:

不,您无法控制图像的动画。

您需要每个图像的两个版本,一个是动画的,一个不是。悬停时,您可以轻松地从一张图像更改为另一张图像。

例子:

$(function(){
  $('img').each(function(e){
    var src = $(e).attr('src');
    $(e).hover(function(){
      $(this).attr('src', src.replace('.gif', '_anim.gif'));
    }, function(){
      $(this).attr('src', src);
    });
  });
});

更新:

时间在流逝,可能性也在改变。正如 kritzikatzi 指出的那样,拥有两个版本的图像并不是唯一的选择,您显然可以使用画布元素来创建动画第一帧的副本。请注意,这并不适用于所有浏览器,例如 IE 8 不支持 canvas 元素。

【讨论】:

  • 这个答案只是部分正确。现在您可以使用 canvas 标签从 gif 的第一帧创建静止图像(freezeframe 插件就是这样做的)。显然有两个版本可能会为您节省大量带宽,只是说这不是唯一的选择。
  • @kritzikratzi:请注意,画布技巧仅适用于与页面本身来自同一域的图像。 Canvas 无法捕获从其他地方加载的图像。
  • 为什么投反对票?如果你不解释你认为错的地方是什么,它就无法改进答案。
  • 赞成,因为这是一个很好的解决方案,尽管人们拒绝投票给你一个只有 3 年历史的答案,但你仍然继续更新它,一开始就没有错。谢谢,这有帮助。
  • @TheDembinski:是的,在某些情况下这将是一个更好的解决方案,这完全取决于您拥有多少图像以及您愿意预加载多少数据。如果你在悬停时切换元素,你甚至可以只使用 CSS。
【解决方案2】:

最好的选择可能是有一个静止图像,当你想停止它时,你用它替换 gif。

    <img src="gif/1303552574110.1.gif" alt="" class="anim" >
    <img src="gif/1302919192204.gif" alt="" class="anim" >
    <img src="gif/1303642234740.gif" alt="" class="anim" >
    <img src="gif/1303822879528.gif" alt="" class="anim" >
    <img src="gif/1303825584512.gif" alt="" class="anim" >
    $(window).load(function() {
      $(".anim").src("stillimage.gif");
    });

    $(".anim").mouseover(function {
      $(this).src("animatedimage.gif");
    });

    $(".anim").mouseout(function {
      $(this).src("stillimage.gif");
    });

您可能希望有两个数组,其中包含可以分配给每个图像的静态和动画 gif 的路径。

【讨论】:

    【解决方案3】:

    据我所知,只有一种方法。

    有 2 张图片,首先是带有 gif 第一帧(或任何您想要的)的 jpeg 和实际 gif。

    用 jpeg 加载页面并在鼠标悬停时将 jpeg 替换为 gif。您可以根据需要预加载 gif,或者如果它们是大尺寸的,则在加载 gif 时显示加载,然后用它替换 jpeg。

    如果你想让它变成双线性的,比如在鼠标悬停时播放 gif,在鼠标移出时停止它,然后从你停止的帧恢复播放,那么这不能用 javascript+gif 组合来完成。

    【讨论】:

      【解决方案4】:

      我意识到这个答案已经晚了,但是我找到了一个相当简单、优雅和有效的解决这个问题的方法,觉得有必要把它贴在这里。

      但是我觉得我需要明确的一件事是,这不会在鼠标悬停时启动 gif 动画,在鼠标悬停时暂停它,并在您再次将鼠标悬停时继续它。不幸的是,这对于 GIF 是不可能的。 (可以将一个接一个显示的图像字符串看起来像 gif,但是将 gif 的每一帧都拆开并将所有这些 url 复制到脚本中会很耗时)

      我的解决方案是让图像看起来像是在鼠标悬停时开始移动。您将 gif 的第一帧设为图像并将该图像放在网页上,然后在鼠标悬停时将图像替换为 gif,它看起来就像开始移动。它会在鼠标移出时重置。

      只需将此脚本插入 HTML 的头部:

      $(document).ready(function()
      {
          $("#imgAnimate").hover(
              function()
              {
                  $(this).attr("src", "GIF URL HERE");
              },
              function()
              {
                  $(this).attr("src", "STATIC IMAGE URL HERE");
              });
      });
      

      并将这段代码放在你想要动画的图片的img标签中。

      id="imgAnimate"
      

      这将在鼠标悬停时加载 gif,因此看起来您的图像开始移动。 (这比加载 gif onload 更好,因为从静态图像到 gif 的过渡是不稳定的,因为 gif 将在随机帧上开始)

      对于多个图像,只需 重新创建脚本 创建一个函数:

      <script type="text/javascript">
      
      var staticGifSuffix = "-static.gif";
      var gifSuffix = ".gif";
      
      $(document).ready(function() {
      
        $(".img-animate").each(function () {
      
           $(this).hover(
              function()
              {
                  var originalSrc = $(this).attr("src");
                  $(this).attr("src", originalSrc.replace(staticGifSuffix, gifSuffix));
              },
              function()
              {
                  var originalSrc = $(this).attr("src");
                  $(this).attr("src", originalSrc.replace(gifSuffix, staticGifSuffix));  
              }
           );
      
        });
      
      });
      </script>
      
      </head>
      <body>
      
      <img class="img-animate" src="example-static.gif" >
      <img class="img-animate" src="example-static.gif" >
      <img class="img-animate" src="example-static.gif" >
      <img class="img-animate" src="example-static.gif" >
      <img class="img-animate" src="example-static.gif" >
      
      </body>
      

      该代码块是一个正常运行的网页(基于您提供给我的信息),它将显示静态图像并在悬停时加载和显示 gif。您所要做的就是插入静态图片的网址。

      【讨论】:

      • 这对我很有效。其他解决方案对我不起作用。
      • 谢谢,我试试 =p 我用很多我第一次错过的东西更新了这个答案。 (还修复了一个错误,即我忘记更改脚本版本中的 ID 名称)
      • 不,谢谢!这是我实施这项技术的地方:new.syntheticmedia.net 将鼠标悬停在徽标和导航菜单项上。
      • 那绝对是糟糕的代码。你永远不应该像那样复制代码;而是在 DOM 中搜索图像:$("img").each(function () { $(this).hover(function () { ... }) }); 并使用命名约定
      【解决方案5】:

      您可以通过逐步显示长条来解决此问题,例如幻灯片。然后你可以在任何帧上停止电影。 下面的示例(小提琴可在http://jsfiddle.net/HPXq4/9/ 获得):

      标记:

       <div class="thumbnail-wrapper">
           <img src="blah.jpg">
       </div>
      

      CSS:

      .thumbnail-wrapper{
         width:190px;
         height:100px;
         overflow:hidden;
         position:absolute;
      }
      .thumbnail-wrapper img{
         position:relative;
         top:0;
      }
      

      js:

      var gifTimer;
      var currentGifId=null;
      var step = 100; //height of a thumbnail
      $('.thumbnail-wrapper img').hover(
         function(){
            currentGifId = $(this)
            gifTimer = setInterval(playGif,500);
         },
         function(){
             clearInterval(gifTimer);
             currentGifId=null;
         }
      );
      
      var playGif = function(){
         var top = parseInt(currentGifId.css('top'))-step;
         var max = currentGifId.height();
         console.log(top,max)
         if(max+top<=0){
           console.log('reset')
           top=0;
         }
         currentGifId.css('top',top);
      }
      

      显然,这可以进一步优化,但为了便于阅读,我简化了这个示例

      【讨论】:

        【解决方案6】:

        我认为jQuery plugin freezeframe.js 可能会为您派上用场。 freezeframe.js 是一个 jQuery 插件,用于在鼠标悬停时自动暂停 GIF 并重新启动动画。

        我想您可以轻松地对其进行调整以使其在页面加载时工作。

        【讨论】:

        • 这个解决方案可能更健壮,它在部分工作中使用了画布元素,但它为 OP 提出的总体基本要求增加了很多开销。
        • 不幸的是,这里的链接和@tabacitu 的链接似乎都不再起作用了。看起来该插件在 gitHub 上可用:github.com/chrisantonellis/freezeframe.js
        【解决方案7】:

        Mark Kramer 的一个更优雅的版本是执行以下操作:

        function animateImg(id, gifSrc){
          var $el = $(id),
            staticSrc = $el.attr('src');
          $el.hover(
            function(){
              $(this).attr("src", gifSrc);
            },
            function(){
              $(this).attr("src", staticSrc);
            });
        }
        
        $(document).ready(function(){
          animateImg('#id1', 'gif/gif1.gif');
          animateImg('#id2', 'gif/gif2.gif');
        });
        

        或者更好的是使用数据属性:

        $(document).ready(function(){
          $('.animated-img').each(function(){
            var $el = $(this),
              staticSrc = $el.attr('src'),
              gifSrc = $el.data('gifSrc');
            $el.hover(
              function(){
                $(this).attr("src", gifSrc);
              },
              function(){
                $(this).attr("src", staticSrc);
              });
          });
        });
        

        img el 看起来像:

        <img class="animated-img" src=".../img.jpg" data-gif-src=".../gif.gif" />
        

        注意:此代码未经测试,但应该可以正常工作。

        【讨论】:

          【解决方案8】:

          重新启动gif图片的动画,可以使用代码:

          $('#img_gif').attr('src','file.gif?' + Math.random());
          

          【讨论】:

            【解决方案9】:

            像这样添加后缀:

            $('#img_gif').attr('src','file.gif?' + Math.random());  
            

            每次用户访问该页面时,浏览器都会强制下载一个新图像。此外,客户端缓存可能会很快被填满。

            以下是我在 Chrome 49 和 Firefox 45 上测试的替代解决方案。
            在 css 样式表中将显示属性设置为“无”,如下所示:

            #img_gif{
              display:'none';
            }
            

            在'$(document).ready'语句外插入:

            $(window).load(function(){ $('#img_gif').show(); });

            每次用户访问页面时,动画会在所有元素加载完成后启动。这是我发现sincronize gif 和html5 动画的唯一方法。

            请注意:
            刷新页面(如按“F5”)后,gif动画不会重新启动。
            “$(document).ready”语句不会产生与“$(window).load”相同的效果。
            属性“可见性”不会产生与“显示”相同的效果。

            【讨论】:

              【解决方案10】:

              相关答案,你可以指定一个gif的播放次数。下面的 gif 有 3 个与之关联的播放(10 秒计时器,总共 30 秒播放)。自页面加载后 30 秒后,它会在“0:01”处停止。

              刷新页面以重新开始所有 3 次播放

              您必须修改 gif 本身。在这里可以找到一个简单的工具来修改 GIF 播放 https://ezgif.com/loop-count

              要查看登录页面上的单循环播放 gif 示例,请使用单个播放 gif https://git-lfs.github.com/ 查看此站点

              【讨论】:

                【解决方案11】:

                在这里找到了一个可行的解决方案: https://codepen.io/hoanghals/pen/dZrWLZ

                这里是JS:

                var gifElements = document.querySelectorAll('img.gif');
                
                for(var e in gifElements) {
                
                var element = gifElements[e];
                
                if(element.nodeName == 'IMG') {
                
                    var supergif = new SuperGif({
                        gif: element,
                        progressbar_height: 0,
                        auto_play: false,
                    });
                
                    var controlElement = document.createElement("div");
                    controlElement.className = "gifcontrol loading g"+e;
                
                    supergif.load((function(controlElement) {
                        controlElement.className = "gifcontrol paused";
                        var playing = false;
                        controlElement.addEventListener("click", function(){
                            if(playing) {
                                this.pause();
                                playing = false;
                                controlElement.className = "gifcontrol paused";
                            } else {
                                this.play();
                                playing = true;
                                controlElement.className = "gifcontrol playing";
                            }
                        }.bind(this, controlElement));
                
                    }.bind(supergif))(controlElement));
                
                    var canvas = supergif.get_canvas();     
                    controlElement.style.width = canvas.width+"px";
                    controlElement.style.height = canvas.height+"px";
                controlElement.style.left = canvas.offsetLeft+"px";
                    var containerElement = canvas.parentNode;
                    containerElement.appendChild(controlElement);
                
                 }
                }
                

                【讨论】:

                • 这很好用。谢谢!然而,你错过了一件事。需要库buzzfeed / libgif-js 。见下文,我在这里给出了完整的答案,而不仅仅是 JavaScript。
                【解决方案12】:

                css 过滤器可以阻止 gif 在 chrome 中播放

                添加

                filter: blur(0.001px);
                

                到您的 img 标签,然后 gif 冻结以通过 chrome 性能问题加载 :)

                【讨论】:

                  【解决方案13】:

                  这个答案建立在 Sourabh 的基础上,他在 https://codepen.io/hoanghals/pen/dZrWLZ 上指出了一个 HTML/CSS/JavaScript 组合来完成这项工作。我尝试了这个,并制作了一个完整的网页,包括我在我的网站上尝试过的 CSS 和 JavaScript。由于 CodePens 有消失的习惯,我决定在这里展示一下。我还展示了一个简化的精简版,以展示一个人需要做的最低限度的工作。

                  我还必须注意一件事。上面链接中的代码(其 JavaScript Sourabh 复制了该代码)引用了 JavaScript 构造函数 SuperGif() 。我认为 Sourabh 没有解释这一点,CodePen 也没有。一个简单的搜索表明它是在buzzfeed / libgif-js ,可以从https://github.com/buzzfeed/libgif-js#readme 下载。查找下方红色箭头所指的控件,然后单击绿色的“代码”按钮。 (注意,你不会看到红色箭头:那是我告诉你在哪里看。)

                  将弹出一个菜单,提供各种选项,包括下载 zip 文件。下载它,并将其解压缩到您的 HTML 目录或其子目录中。

                  接下来,我将展示我制作的两个页面。第一个是从 CodePen 派生的。第二个被剥离了它的基本要素,并显示了使用 SuperGif 所需的最低限度。

                  这是第一页的完整 HTML、CSS 和 JavaScript。 HTML 的头部是指向 libgif.js 的链接,这是您需要的 zip 文件中的文件。然后,HTML 的正文以一些关于猫图片的文本开头,然后是一个指向动画猫 GIF 的链接,地址为 https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif

                  然后继续使用一些 CSS。 CodePen 使用 SCSS,任何不知道的人都必须将其预处理为 CSS。我已经这样做了,所以下面的代码是真正的 CSS。

                  最后是 JavaScript。

                  <html>
                  <head>
                  <script src="libgif-js-master/libgif.js"></script> 
                  </head>
                  
                  <body>
                  
                  <div style="width: 600px; margin: auto; text-align: center; font-family: arial">
                    <p>
                  And so, the unwritten law of the internet, that any 
                  experiment involving video/images must involve cats in 
                  one way or another, reared its head again. When would 
                  the internet's fascination with cats come to an end? 
                  Never. The answer is "Never".
                  </p> 
                    <img src='https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif' class='gif' />
                  </div>
                  
                  <style>
                  img.gif {
                    visibility: hidden;
                  }
                  
                  .jsgif {
                    position: relative;
                  }
                  
                  .gifcontrol {
                    position: absolute;
                    top: 0px;
                    left: 0px;
                    width: 100%;
                    height: 100%;
                    cursor: pointer;
                    transition: background 0.25s ease-in-out;
                    z-index: 100;
                  }
                  .gifcontrol:after {
                    transition: background 0.25s ease-in-out;
                    position: absolute;
                    content: "";
                    display: block;
                    left: calc(50% - 25px);
                    top: calc(50% - 25px);
                  }
                  .gifcontrol.loading {
                    background: rgba(255, 255, 255, 0.75);
                  }
                  .gifcontrol.loading:after {
                    background: #FF9900;
                    width: 50px;
                    height: 50px;
                    border-radius: 50px;
                  }
                  .gifcontrol.playing {
                    /* Only show the 'stop' button on hover */
                  }
                  .gifcontrol.playing:after {
                    opacity: 0;
                    transition: opacity 0.25s ease-in-out;
                    border-left: 20px solid #FF9900;
                    border-right: 20px solid #FF9900;
                    width: 50px;
                    height: 50px;
                    box-sizing: border-box;
                  }
                  .gifcontrol.playing:hover:after {
                    opacity: 1;
                  }
                  .gifcontrol.paused {
                    background: rgba(255, 255, 255, 0.5);
                  }
                  .gifcontrol.paused:after {
                    width: 0;
                    height: 0;
                    border-style: solid;
                    border-width: 25px 0 25px 50px;
                    border-color: transparent transparent transparent #ff9900;
                  }
                  </style>
                  
                  <script>
                  var gifElements = document.querySelectorAll('img.gif');
                  
                  for(var e in gifElements) {
                    
                      var element = gifElements[e];
                      
                      if(element.nodeName == 'IMG') {
                      
                          var supergif = new SuperGif({
                              gif: element,
                              progressbar_height: 0,
                              auto_play: false,
                          });
                  
                          var controlElement = document.createElement("div");
                          controlElement.className = "gifcontrol loading g"+e;
                  
                          supergif.load((function(controlElement) {
                              controlElement.className = "gifcontrol paused";
                              var playing = false;
                              controlElement.addEventListener("click", function(){
                                  if(playing) {
                                      this.pause();
                                      playing = false;
                                      controlElement.className = "gifcontrol paused";
                                  } else {
                                      this.play();
                                      playing = true;
                                      controlElement.className = "gifcontrol playing";
                                  }
                              }.bind(this, controlElement));
                          
                          }.bind(supergif))(controlElement));
                      
                          var canvas = supergif.get_canvas();     
                          controlElement.style.width = canvas.width+"px";
                          controlElement.style.height = canvas.height+"px";
                      controlElement.style.left = canvas.offsetLeft+"px";
                          var containerElement = canvas.parentNode;
                          containerElement.appendChild(controlElement);
                      
                    }
                  }
                  </script>
                  
                  </body>
                  </html>
                  

                  当我将页面放到我的网站上并显示它时,顶部看起来是这样的:

                  当我按下粉色按钮时,页面变成了这个,GIF 开始动画。 (猫舔着水龙头里掉下来的水。)

                  最后,这是第二个简单的页面。与第一个不同,它没有花哨的播放/暂停控件来改变形状:它只有两个按钮。代码唯一不需要做的事情就是禁用不相关的按钮,并在按钮之间插入一些空格。

                  <html>
                  
                  <head>
                  <script src="libgif-js-master/libgif.js"></script>
                  </head>
                  
                  <body>
                  
                  <button type="button" onclick="play()"
                          id="play_button"
                          style="margin-right:9px;"
                  >
                  Play
                  </button>
                        
                  <button type="button" onclick="pause()"
                          id="pause_button"
                  >
                  Pause
                  </button>
                  
                  <img src="https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif" 
                       id="gif" 
                  />
                  
                  <script>
                  var gif_element = document.getElementById( "gif" );
                      
                  var supergif = new SuperGif( {
                               gif: gif_element,
                                            progressbar_height: 0,
                                            auto_play: false
                                 } );
                  
                  supergif.load();
                  
                  function play()
                  {
                    var play_button = document.getElementById( "play_button" );
                    play_button.disabled = true;
                  
                    var pause_button = document.getElementById( "pause_button" );
                    pause_button.disabled = false;
                   
                    supergif.play();
                  }
                  
                  function pause()
                  {
                    var play_button = document.getElementById( "play_button" );
                    play_button.disabled = false;
                  
                    var pause_button = document.getElementById( "pause_button" );
                    pause_button.disabled = true;
                  
                    supergif.pause();
                  }
                  
                  pause_button.disabled = true;
                  </script>
                  
                  </body>
                  </html>
                  

                  这个,加上 libgif-js 中的 example.html 文件,应该足以让任何人开始。

                  【讨论】:

                    【解决方案14】:

                    纯JS实现https://jsfiddle.net/clayrabbit/k2ow48cy/ (基于https://codepen.io/hoanghals/pen/dZrWLZ的画布解决方案)

                    [].forEach.call(document.querySelectorAll('.myimg'), function(elem) {
                        var img = new Image();
                        img.onload = function(event) {
                        elem.previousElementSibling.getContext('2d').drawImage(img, 0, 0);
                        };
                      img.src = elem.getAttribute('data-src');
                      
                        elem.onmouseover = function(event) {
                            event.target.src = event.target.getAttribute('data-src');
                        };
                        elem.onmouseout = function(event) {
                            event.target.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII=";
                        };
                    });
                    .mydiv{
                      width: 320px;
                      height: 240px;
                      position: relative;
                    }
                    .mycanvas, .myimg {
                      width: 100%;
                      height: 100%;
                      position: absolute;
                    }
                    <div class="mydiv">
                    <canvas class="mycanvas" width=320 height=240></canvas>
                    <img class="myimg" data-src="https://media.giphy.com/media/Byana3FscAMGQ/giphy.gif">
                    </div>

                    【讨论】:

                      猜你喜欢
                      • 2012-07-22
                      • 1970-01-01
                      • 2012-01-23
                      • 1970-01-01
                      • 1970-01-01
                      • 2012-05-04
                      • 2013-12-09
                      • 1970-01-01
                      相关资源
                      最近更新 更多