【问题标题】:Can you control GIF animation with Javascript?你能用 JavaScript 控制 GIF 动画吗?
【发布时间】:2011-01-24 00:29:03
【问题描述】:

是否可以使用 javascript 来控制 GIF 图像的哪一帧正在显示和/或停止动画。我希望能够加载带有多个帧的GIF,并且只显示其中一个。

我知道我可以用很多单独的图片来做,但如果我可以用GIF 做我想做的事,那只需担心一个文件。

【问题讨论】:

  • 你也可以用一张带有精灵的大图像来做,只通过剪裁图像来显示精确的精灵
  • 同意@MBO,使用精灵相当简单,检查这个相关问题:stackoverflow.com/questions/1736922/…
  • 使用无声视频。就像 9gag
  • 我认为简短的回答是否定的。如果你想使用 JavaScript,你最有可能的选择是控制真正的视频或使用 CSS sprites。使用 CSS sprites 的好处是您最终会传输单个图像,并且该图像比多个单个图像具有更好的整体压缩。

标签: javascript css animation gif animated-gif


【解决方案1】:

您可以使用libgif 库。

它允许您启动/停止 gif 并控制 gif 所在的帧。

<script type="text/javascript" src="./libgif.js"></script>
<img src="./example1_preview.gif" rel:animated_src="./example1.gif"
 width="360" height="360" rel:auto_play="1" rel:rubbable="1" />

<script type="text/javascript">
    $$('img').each(function (img_tag) {
        if (/.*\.gif/.test(img_tag.src)) {
            var rub = new SuperGif({ gif: img_tag } );
            rub.load(function(){
                console.log('oh hey, now the gif is loaded');
            });
        }
    });
</script>

(大部分代码直接取自他们的示例)

【讨论】:

  • 这段代码似乎对我不起作用。它用sup1.load() 播放gif,然后当gif 完成后,它会用sup1.move_to(frame) 转到第一帧。我也尝试使用pause(),但它似乎也没有冻结第一帧的 gif。我编辑了原始代码,使其在第一帧停止,但是有没有办法在第一帧暂停 gif 而无需编辑代码?
  • @LeoCHan 我已经将示例代码更新为最新的api,现在试试吧
  • 这个答案比接受的答案更好地解决了这个问题。
  • 我一定在这里遗漏了一些东西。 $$ 是什么?我不确定。
  • 非常重要的是要注意此库细则中的警告。 Caveat: same-domain origin. The gif has to be on the same domain (and port and protocol) as the page you're loading.
【解决方案2】:

我使用x-gif,它非常酷且易于设置。

来自Github

<x-gif src="probably_cats.gif"></x-gif>

您可以在其中添加以下属性:

  • 播放模式:
    • speed="1.0"(默认模式)将速度乘以属性值;
    • sync 延迟播放到外部对象;
    • bpm="120" 将 GIF 同步到给定的每分钟节拍;
  • 选项:

    • stopped 阻止 GIF 动画;

    • fill 导致 GIF 展开以覆盖其容器;

    • n-times="3.0"(仅限速度模式)在设定的次数后停止播放(通过添加停止的属性);
    • snap(仅限同步和 bpm 模式)不要让较长的 GIF 同步到多个节拍,而是强制它们只适合一个节拍;
    • ping-pong 前后播放 GIF;
  • 调试:
    • debug 打开 Gif Exploder 的调试输出;
    • exploded 停止播放,并排渲染每一帧。

【讨论】:

  • 在他们的Github 页面上,它的工作原理是这样的&lt;x-gif src="probably_cats.gif"&gt;&lt;/x-gif&gt;:您可以为这个标签添加几个属性,包括播放模式、选项和调试。我尝试编辑您提供summary with them 的答案,但被拒绝,如果您有时间,您可以自己编辑。
【解决方案3】:

如果您可以将 gif 转换为精灵表,您可以这样做(使用 ImageMagick):

montage animation.gif -coalesce -tile x1 -geometry +0+0 -background None -quality 100 spritesheet.png

新图像的尺寸甚至可能更小。

一旦有了精灵表,就可以使用 CSS 动画。这里使用了固定帧时间的动画:

var el = document.getElementById('anim');
function play() {
  el.style.animationPlayState = 'running';
}
function pause() {
  el.style.animationPlayState = 'paused';
}
function reset() {
  el.style.animation = 'none';
  el.offsetHeight; /* trigger reflow to apply the change immediately */
  el.style.animation = null;
}
function stop() {
  reset();
  pause();
}
#anim {
  background-image: url('https://i.stack.imgur.com/J5drY.png');
  width: 250px;
  height: 188px;
  animation: anim 1.0s steps(10) infinite;
}
@keyframes anim {
  100% { background-position: -2500px; }
}
<div id="anim" title="Animated Bat by Calciumtrice"></div>
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button>
<button onclick="reset()">Reset</button>
<button onclick="stop()">Stop</button>

如果您不希望动画自动开始,请将paused 添加到animation 规则的末尾。

【讨论】:

  • 这是解决这个问题的绝佳而简单的方法,gratz!
  • 这个方法对我有用;它很容易实现并根据您的喜好进行调整。我在这里使用 ezgif 来创建我的工作表:ezgif.com/gif-to-sprite
  • 我知道这是一个古老的问题和答案,但我有一个问题。我非常喜欢这个答案,我想知道您是否可以隐藏或使动画 GIF 消失,然后用这个答案重新出现。
【解决方案4】:

您可以使用CSS sprites 对单个图像执行此操作。

【讨论】:

  • 这是正确的,只要人们想要在 2D 平面周围分割图像的不同变体,而不是将其分割为单独的帧。
猜你喜欢
  • 2011-09-13
  • 2012-05-23
  • 2016-03-20
  • 2011-11-06
  • 1970-01-01
  • 2019-05-24
  • 2019-05-13
  • 1970-01-01
相关资源
最近更新 更多