Делаем анимированные иконки в стиле твиттера
09.05.2016 14:51
3Понравилось мне, как себя видет иконка "избранное" и иконка "нравится" в 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 пикселей).
Все очень и очень просто. Однако, данную анимацию, по-идее, можно применить для любой иконки, не храня для нее по отдельному длинному спрайту с анимацией.
Анимация представляет собой разлет цветных "брызг", внутри которых появляется нужная иконка следующим образом:
- размер меняется сначала от 0 до чуть больше своего настоящего размера
- затем меняется от текущего размера до своего настоящего размера
Это запросто можно сделать средствами CSS с любой картинкой например используя transform: scale().
Тогда нам нужно всего-лишь иметь один спрайт с анимацией брызг на все случаи наших иконок и по одной картинке для каждой из них.
Сам спрайт достается из твиттера (а можно и свой нарисовать), вот он:
Все остальное можно сделать с помощью фильтров и трансформаций.
При анимации мы просто прокручиваем анимацию брызг под нашей иконкой, а саму иконку анимируем отдельно с помощью масштабирования - вот и все.
Демо
нажмите на иконку и держите ее нажатой, чтобы анимация проигрывалась
Получилось достаточно похоже и экономней с точки зрения ресурсов. Минусы есть - куда без них - используется мощь CSS3 селекторов - если браузер что-то из этого не понимает, то все это не будет работать.
Можно что-то частично соптимизировать - например не использовать filter, заменив его просто еще одной иконкой.
Также, вместо transform: scale() можно использовать width/height, а вместо transform: translate(), который используется для выравнивания по вертикали и горизонтали использовать margin при известном размере иконки.
Весь код |
/* убираем выделение с икноки */ .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>
09.05.2016, Protocoder