Делаем анимированные иконки в стиле твиттера

09.05.2016 14:51
0

Понравилось мне, как себя видет иконка "избранное" и иконка "нравится" в Twitter.

У них используется достаточно простое решение - обычный спрайт, куда вписана по-кадрово анимация:
.icon {
	width: 100px;
	height: 100px;
	background: url( "sprite.png" ) no-repeat;
	background-position: -2100px 0;
	animation: twFav 1s steps( 20 );
}
 
@keyframes twFav {
	 0% {
		background-position: 0 0;
	}
	100% {
		background-position: -2000px 0;
	}
}

Где sprite.png - файл со спрайтом, размер спрайта 100x100 пикселей, а спрайтов всего 20 - соответственно шагов (кадров) анимации тоже 20.
Изначально, чтобы не было видно первого кадра устанавливается позиция в -21 кадр (-21 * 100 = -2100 пикселей), а сама анимация идет 0 до 20 кадра (20 * 100 = 2000 пикселей).

Все очень и очень просто. Однако, данную анимацию, по-идее, можно применить для любой иконки, не храня для нее по отдельному длинному спрайту с анимацией.

Анимация представляет собой разлет цветных "брызг", внутри которых появляется нужная иконка следующим образом:
  1. размер меняется сначала от 0 до чуть больше своего настоящего размера
  2. затем меняется от текущего размера до своего настоящего размера

Это запросто можно сделать средствами CSS с любой картинкой например используя transform: scale().

Тогда нам нужно всего-лишь иметь один спрайт с анимацией брызг на все случаи наших иконок и по одной картинке для каждой из них.

Сам спрайт достается из твиттера (а можно и свой нарисовать), вот он:

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

Демо

нажмите на иконку и держите ее нажатой, чтобы анимация проигрывалась

Получилось достаточно похоже и экономней с точки зрения ресурсов. Минусы есть - куда без них - используется мощь CSS3 селекторов - если браузер что-то из этого не понимает, то все это не будет работать.

Можно что-то частично соптимизировать - например не использовать filter, заменив его просто еще одной иконкой.
Также, вместо transform: scale() можно использовать width/height, а вместо transform: translate(), который используется для выравнивания по вертикали и горизонтали использовать margin при известном размере иконки.

Весь код
CSS:
/* убираем выделение с икноки */
.twAni,
.twAni img {
	-webkit-touch-callout: none;
	-webkit-user-select: none;
	-moz-user-select: none;
	-ms-user-select: none;
	user-select: none;
}
 
/* основной слой - анимация брызг */
.twAni {
	position: relative;
	z-index: 0;
	width: 100px;
	height: 100px;
	background: url( "twAniBG.png" ) no-repeat;
	background-position: -2100px 0;
	cursor: pointer;
	animation: none;
}
 
/* при нажатии кнопки мышки - запускаем анимацию брызг */
.twAni:active {
	animation: twAni 1s steps( 20 );
}
 
/* анимация брызг */
@keyframes twAni {
	 0% {
		background-position: 0 0;
	}
	100% {
		background-position: -2000px 0;
	}
}
 
/* картинка с нужной иконкой */
.twAni img {
	position: absolute;
	left: 50%;
	top: 50%;
	z-index: 1;
	border: none;
	text-decoration: none;
	opacity: 0.5;
	filter: grayscale( 100% );
	transform: translate( -50%, -50% ) scale( 1 );
	transition: opacity 0.2s linear;
	animation: none;
}
 
/* "проявление" иконки при наведении */
.twAni:hover img {
	opacity: 1;
}
 
/* при нажатии кнопки мышки - запускаем анимацию иконки */
.twAni:active img {
	opacity: 1;
    filter: none;
	transition: none;
	animation: twAniIco 0.4s ease-in-out;
}
 
/* анимация иконки */
@keyframes twAniIco {
	0% {
        transform: translate( -50%, -50% ) scale( 0 );
	}
 
	70% {
        transform: translate( -50%, -50% ) scale( 1.2 );
	}
 
	100% {
        transform: translate( -50%, -50% ) scale( 1 );
	}
}

HTML:
	<div class="twAni" draggable="false"><img src="thumbup.png" draggable="false" /></div>

Скачать все файлы одним архивом

twAni.zip
скачать

09.05.2016, Protocoder
Написать комментарий