Как показать анимированное изображение из изображения PNG с помощью javascript? [как гмейл]

Прежде всего, посмотрите это изображение
wink
Gmail использует это изображение для отображения анимированного смайлика.
Как мы можем показать такую ​​анимацию с помощью изображения png?


person Rakesh Juyal    schedule 15.11.2009    source источник


Ответы (6)


Я оставляю вам грубый пример, чтобы вы могли получить отправную точку:

Я буду использовать простой элемент div с width и height, которые будут иметь анимированное изображение, спрайт png как background-image и 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'))

EDIT: Вы также можете установить свойства CSS программно, чтобы вам не нужно было определять какой-либо стиль на своей странице, и создать функция-конструктор из приведенного выше примера, которая позволит вам одновременно отображать несколько анимаций спрайтов:

Использование:

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();

Проверьте приведенный выше пример здесь.

person Christian C. Salvadó    schedule 15.11.2009
comment
+1 За один из самых подробных ответов на довольно простой вопрос - person Ben Shelock; 16.11.2009
comment
Отличный ответ, отличная реализация. В качестве примечания к сайту: если ваша анимация становится все более сложной: spritely.net кажется хорошим и маленьким lib для всего, что связано с анимацией спрайтов. - person bitbonk; 30.05.2013
comment
Спасибо за это, однако я не понимаю использование двух анонимных функций в первом примере (зачем возвращать функцию?). - person kursus; 12.07.2013
comment
Расположение изображения изменилось, новый URL-адрес изображения ssl.gstatic. com/ui/v1/icons/mail/im/emotisprites/wink2.png - person deepakmodak; 09.09.2014
comment
Я просто хотел бы добавить, что эту технику также можно использовать без JS для простых анимаций с использованием функции steps() в CSS: blog.teamtreehouse.com/css-sprite-sheet-animations-steps - person bernk; 19.02.2015

Взгляните на это:
http://www.otanistudio.com/swt/sprite_explosions/ и http://www.alistapart.com/articles/sprites ответ лежит в пределах.

person roufamatic    schedule 15.11.2009

Ответ CMS в порядке, но есть также формат APNG (анимированный PNG), который вы, возможно, захотите использовать вместо этого. Конечно, первый кадр (тот, который отображается даже в браузерах, не поддерживающих APNG) должен быть «конечным» кадром и просто указать, чтобы пропустить первый кадр в файле.

person Eli Grey    schedule 16.11.2009
comment
приятно узнать о новом формате. Но я просто хотел знать, как мы можем показать анимацию, используя статический PNG. - person Rakesh Juyal; 16.11.2009

Установите фоновое изображение элемента на первое изображение, затем используйте javascript, чтобы изменить изображение, изменяя стиль каждые x миллисекунд.

person klaaspieter    schedule 15.11.2009
comment
пожалуйста, скажите мне, как это сделать. change the image every x milli - person Rakesh Juyal; 15.11.2009

Вы можете сделать это с помощью TweenMax и замедления stepEase: http://codepen.io/burnandbass/pen/FfeAa или http://codepen.io/burnandbass/pen/qAhpj на ваш выбор :)

person Chris Panayotoff    schedule 02.06.2013

В этом случае можно использовать CSS @keyframes.

@keyframes smile {
    0% { background-postiion: 0 -16px;}
    5% { background-postiion: 0 -32px;}
    10% { background-postiion: 0 -48px;}
    /*...etc*/
}
person Undefitied    schedule 15.12.2016
comment
Я думал об этом, как вы думаете, это может показать какой-то сбой? как половина первого изображения и половина второго изображения? - person shunz19; 06.07.2017