你能用Javascript控制GIF动画吗?

问题描述 投票:0回答:5

是否可以使用javascript来控制

GIF
图像的哪一帧正在显示和/或停止动画。我希望能够加载带有多个帧的
GIF
并且仅显示其中之一。

我知道我可以用很多单独的图像来完成,但如果我可以用

GIF
做我想做的事情,那么只需担心一个文件。

javascript css animation gif animated-gif
5个回答
70
投票

您可以使用 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>

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


35
投票

如果您同意将 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
规则的末尾。


33
投票

我使用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
      停止播放,并并排渲染每个帧。

12
投票

您可以使用 CSS sprites 用单个图像来完成此操作。


0
投票

2024 年更新

这个问题是2010年发布的,需要更新。前面的答案使用了很少使用的技术和库。然而,它仍然被认为是一种解决方案。

截图

浏览器现在支持视频元素。这些不会直接播放动画 GIF 图像。然而,使用图形应用程序或众多在线转换器之一将 GIF 图像转换为 MP4 格式非常容易。当需要透明背景时,WEBM 格式是一种广泛支持的替代方案。

视频比 GIF 动画有很多优点。其中一些是:

  • 大大减小文件大小
  • 不需要任何库
  • 加载时播放
  • 使用媒体的能力资源
  • 视觉效果与 GIF 相同
  • 还有更多...

代码片段

该片段并排播放 MP4、WEBM 和 GIF。 MP4 和 WEBM 使用 HTML-5 video 元素。 GIF 使用来自得票最多的答案的library。有播放、暂停和搜索按钮。

const toggle = document.querySelector('input[type=checkbox]');
const mp4 = document.querySelector('#mp4 video');
const webm = document.querySelector('#webm video');
const gif = new SuperGif({
  gif: document.querySelector('#gif img'),
  loop_mode: true,
  auto_play: true,
  max_width: 150,
  // on_end:.
  // loop_delay:
  show_progress_bar: false
});

gif.load();

play.addEventListener('click', () => {
  mp4.play();
  webm.play();
  gif.play();
})

pause.addEventListener('click', () => {
  mp4.pause();
  webm.pause();
  gif.pause();
})

seek.addEventListener('change', () => {
  let percent = seek.value / 100;
  let frame = Math.floor(gif.get_length() * percent)
  gif.move_to(frame);
  let position = Math.floor(mp4.duration * percent);
  mp4.currentTime = position;
  position = Math.floor(webm.duration * percent);
  webm.currentTime = position;
})

mp4.addEventListener('timeupdate', () => {
  seek.value = Math.floor(100 * mp4.currentTime / mp4.duration);
});
body {
  font-family: sans-serif;

.container {
  margin-top: 1rem;
  display: flex;
  background-image: linear-gradient(to bottom right, red, yellow);
}

input[type=button] {
  min-width: 4rem;
}
input[type=range] {
  min-width: 20rem;
}
figure {
  border: thin solid white;
  border-radius: 0.5rem;
  display: inline-block;
  padding: 0.25rem;
  margin: 0.5rem;
  background-color: transparent;
}

figcaption {
  color: white;
  text-align: center;
}

video,
img {
  width: 150px;
  height: auto;
}
<input type="button" id="play" value="Play">
<input type="button" id="pause" value="Pause">
<input type="range" id="seek" min="0" max="100" value="0">

<div class="container">
  <figure id="mp4">
    <figcaption>
      205kb Video MP4
    </figcaption>
    <video autoplay muted loop>
      <source src="https://i.yourimageshare.com/i0rmDubApf.mp4">
    </video>
  </figure>

  <figure id="webm">
    <figcaption>
      222kb Video WEBM
    </figcaption>
    <video autoplay muted loop>
      <source src="https://i.yourimageshare.com/S1S9fJww3M.webm">
    </video>
  </figure>

  <figure id="gif">
    <figcaption>
      746kb Animated GIF
    </figcaption>
    <image src="https://i.postimg.cc/t4zZRyZH/rubik.gif" />
  </figure>
</div>



<script src="https://cdn.jsdelivr.net/gh/buzzfeed/libgif-js/libgif.js"></script>

© www.soinside.com 2019 - 2024. All rights reserved.