如何使用JavaScript从PNG图像显示动画图像?[类似于Gmail]

29

首先,查看这张图片
wink
Gmail使用此图像显示动画表情符号。
如何使用png图像显示此类动画呢?

6个回答

71

我为您留下一个简单的示例,以便您有一个起点:

我将使用一个简单的 div 元素,它的 widthheight 与动画图像相同,作为背景图片使用 png 雪碧图,并将 background-repeat 设置为 no-repeat

所需的 CSS:

#anim {
  width: 14px; height: 14px;
  background-image: url(https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png);
  background-repeat: no-repeat; 
}

需要的标记:

<div id="anim"></div>

这个技巧基本上是使用CSS属性background-position将背景图像精灵向上滚动。

我们需要知道动画图片的height(以确定每次向上滚动多少)和要滚动的次数(动画将有多少)。

JavaScript实现:

var scrollUp = (function () {
  var timerId; // stored timer in case you want to use clearInterval later

  return function (height, times, element) {
    var i = 0; // a simple counter
    timerId = setInterval(function () {
      if (i > times) // if the last frame is reached, set counter to zero
        i = 0;
      element.style.backgroundPosition = "0px -" + i * height + 'px'; //scroll up
      i++;
    }, 100); // every 100 milliseconds
  };
})();

// start animation:
scrollUp(14, 42, document.getElementById('anim'))

编辑:你也可以通过编程设置CSS属性,这样就不需要在页面上定义任何样式,并从上面的示例中创建一个构造函数(constructor function),这将允许您同时显示多个精灵动画:

用法:

var wink = new SpriteAnim({
  width: 14,
  height: 14,
  frames: 42,
  sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png",
  elementId : "anim1"
});

var monkey = new SpriteAnim({
  width: 18,
  height: 14,
  frames: 90,
  sprite: "https://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/monkey1.png",
  elementId : "anim4"
});

实现:

function SpriteAnim (options) {
  var timerId, i = 0,
      element = document.getElementById(options.elementId);

  element.style.width = options.width + "px";
  element.style.height = options.height + "px";
  element.style.backgroundRepeat = "no-repeat";
  element.style.backgroundImage = "url(" + options.sprite + ")";

  timerId = setInterval(function () {
    if (i >= options.frames) {
      i = 0;
    }
    element.style.backgroundPosition = "0px -" + i * options.height + "px";
     i++;
  }, 100);

  this.stopAnimation = function () {
    clearInterval(timerId);
  };
}

注意我添加了一个stopAnimation方法,这样你可以通过调用它来停止指定的动画,例如:

monkey.stopAnimation();

请查看上面的例子这里


8
+1 对于一个非常简单的问题,你提供了其中最详尽的回答。 - Ben Shelock
优秀的答案,出色的实现。顺便提一句:如果您的动画内容变得更加复杂,请查看 http://www.spritely.net,它是一个涵盖所有精灵动画相关内容的不错且小巧的库。 - bitbonk
谢谢您提供这个,但是我不理解第一个例子中两个匿名函数的用法(为什么要“return function”?)。 - kursus
1
图片位置已更改,新的图片 URL 为 http://ssl.gstatic.com/ui/v1/icons/mail/im/emotisprites/wink2.png。 - deepakmodak
1
我想补充一下,使用CSS中的steps()函数可以在没有JS的情况下使用此技术进行简单动画:http://blog.teamtreehouse.com/css-sprite-sheet-animations-steps - bernk


3
CMS的回答很好,但你也可以考虑使用APNG(动态PNG)格式。当然,第一帧(即使是不支持APNG的浏览器也会显示的帧)应该是“结束”帧,并且只需指定跳过文件中的第一帧。

1
了解新格式很好。但我只想知道如何使用静态PNG显示动画。 - Rakesh Juyal

1

将元素的背景图像设置为第一张图像,然后使用JavaScript通过每x毫秒更改样式来更改图像。


2
请告诉我如何做到这一点。每x毫秒更改图像 - Rakesh Juyal

0

0
CSS @keyframes 可以在这种情况下使用。
@keyframes smile {
    0% { background-postiion: 0 -16px;}
    5% { background-postiion: 0 -32px;}
    10% { background-postiion: 0 -48px;}
    /*...etc*/
}

我已经考虑过了,你认为它可能会出现一些故障吗?比如第一张图片的一半和第二张图片的一半? - shunz19

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接