以编程方式停止 GIF 动画

Posted

技术标签:

【中文标题】以编程方式停止 GIF 动画【英文标题】:Stopping GIF Animation Programmatically 【发布时间】:2011-04-10 22:45:54 【问题描述】:

我正在开发一个 Twitter 应用程序,它直接从 Twitter 引用图像。 如何防止播放 GIF 动画?

在页面末尾使用 window.stop() 在 Firefox 中对我不起作用。

有更好的 javascript hack 吗?最好这应该适用于所有浏览器

【问题讨论】:

如果您可以使用服务器端语言,我认为您最好使用服务器端代码来获取第一帧,将其存储在您的服务器上并显示它...... 问题是twitter上有15到60张图片要改。请参阅jetwick.com(开源)。 是的,但您只需更改一次,因此应该没有问题。 【参考方案1】:

这有点小技巧,但您可以尝试将 gif 加载到 iframe 中,并在图像加载后从 iframe 内部(在其自身上)调用 window.stop()。这可以防止页面的其余部分停止。

【讨论】:

这会减慢页面渲染速度吗? 我不这么认为,不。试试看! 您介意给我一个代码示例吗?我无法使用您的方法+查看更新 从 iframe 内部调用 window.stop() 也会停止执行原始窗口,或者您将如何执行此操作?【参考方案2】:

这不是一个跨浏览器解决方案,但它在 firefox 和 opera 中有效(不在 ie8 中:-/)。拍摄from here

[].slice.apply(document.images).filter(is_gif_image).map(freeze_gif);

function is_gif_image(i) 
    return /^(?!data:).*\.gif/i.test(i.src);


function freeze_gif(i) 
    var c = document.createElement('canvas');
    var w = c.width = i.width;
    var h = c.height = i.height;
    c.getContext('2d').drawImage(i, 0, 0, w, h);
    try 
        i.src = c.toDataURL("image/gif"); // if possible, retain all css aspects
     catch(e)  // cross-domain -- mimic original with all its tag attributes
        for (var j = 0, a; a = i.attributes[j]; j++)
            c.setAttribute(a.name, a.value);
        i.parentNode.replaceChild(c, i);
    

【讨论】:

据我所知,它使用的是 html5,它应该适用于任何支持 HTML5 的浏览器。据此:deepbluesky.com/blog/-/browser-support-for-css3-and-html5_72IE 仍然不支持。 认为这仅适用于本地动画 gif,而不是托管在不同域上的那些 Library 基于这个答案 脚本有问题,不是吗?如果.drawImage 没有因错误而失败,则不存在CORS 问题并且catch 分支不会执行。但是,如果存在 CORS 问题,则脚本将结束并且无法达到整个 try/catch。我说的对吗? 如果我没记错的话,在 IE8 中的 gif 元素有一个 stop 函数,你可以调用它来停止动画。【参考方案3】:

受@Karussell 答案的启发,我写了 Gifffer。在这里查看https://github.com/krasimir/gifffer

它会自动在您的 Gif 上添加停止/播放控制。

【讨论】:

希望我能 +5 这个。 希望我可以在这里 +5 上一条评论... :) 这是处理此类动画 GIF 的一段很棒的小(但非常聪明)的代码。谢谢 我意识到这是 3 1/2 岁。我不在乎,这并不意味着这仍然不出色。今天把它插入一个页面,效果很好。 如果可以,为什么要额外的 g? @Marvin 我猜你在问为什么额外的“f”。我想“礼物”已经被拿走了。【参考方案4】:

为了改进 Karussell 的回答,这个版本应该是跨浏览器的,冻结所有图像,包括那些文件结尾不正确的图像(例如自动图像加载页面),并且与原始图像的功能不冲突,允许右键单击原件,就好像它正在移动一样。

我会让它检测动画,但这比无论如何都冻结它们要密集得多。

function createElement(type, callback) 
    var element = document.createElement(type);

    callback(element);

    return element;


function freezeGif(img) 
    var width = img.width,
    height = img.height,
    canvas = createElement('canvas', function(clone) 
        clone.width = width;
        clone.height = height;
    ),
    attr,
    i = 0;

    var freeze = function() 
        canvas.getContext('2d').drawImage(img, 0, 0, width, height);

        for (i = 0; i < img.attributes.length; i++) 
            attr = img.attributes[i];

            if (attr.name !== '"')  // test for invalid attributes
                canvas.setAttribute(attr.name, attr.value);
            
        

        canvas.style.position = 'absolute';

        img.parentNode.insertBefore(canvas, img);
        img.style.opacity = 0;
    ;

    if (img.complete) 
        freeze();
     else 
        img.addEventListener('load', freeze, true);
    


function freezeAllGifs() 
    return new Array().slice.apply(document.images).map(freezeGif);


freezeAllGifs();

【讨论】:

以上是关于以编程方式停止 GIF 动画的主要内容,如果未能解决你的问题,请参考以下文章

在颤动中单击时停止 GIF 动画

在 UWP 的 WebView 中停止 GIF 动画

停止循环的 GIF 图标

将 Swing Timer 与 gif 图像同步

在 HTML 中禁用 GIF 动画

如何使 gif 在 UIWebView 中永不停止?