停止加载 gif 动画,鼠标悬停开始激活
Posted
技术标签:
【中文标题】停止加载 gif 动画,鼠标悬停开始激活【英文标题】:Stop a gif animation onload, on mouseover start the activation 【发布时间】:2011-08-14 15:37:03 【问题描述】:我有一个包含很多 GIF 的页面。
<img src="gif/1303552574110.1.gif" >
<img src="gif/1302919192204.gif" >
<img src="gif/1303642234740.gif" >
<img src="gif/1303822879528.gif" >
<img src="gif/1303825584512.gif" >
我在寻找什么
1 页面加载时 => 停止所有 gif 的动画
2 在鼠标悬停时 => 动画为那个 gif 启动
3 On mouseout => 该 gif 动画再次停止
我想这可以在 Jquery 中完成,但我不知道如何。
【问题讨论】:
javascript to control image animation?的可能重复 【参考方案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" class="anim" >
<img src="gif/1302919192204.gif" class="anim" >
<img src="gif/1303642234740.gif" class="anim" >
<img src="gif/1303822879528.gif" class="anim" >
<img src="gif/1303825584512.gif" 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>
【讨论】:
以上是关于停止加载 gif 动画,鼠标悬停开始激活的主要内容,如果未能解决你的问题,请参考以下文章