Круті ефекти при наведенні з використанням Anime.js

15.03.2017 • 6370 переглядів

Круті ефекти при наведенні з використанням Anime.js

Сьогодні ми хотіли б поділитися кількома ідеями крутих ефектів при наведенні. Концепція побудована на ефекті, який Merci-Michel використав у своєму портфоліо. Ефект справді дає приємні відчуття завдяки гальмуванню анімації. Демонстрація результату доступна за посиланням.


Ідея в тому, щоб показати стопку за ескізом, який має той самий основний колір, що й зображення, а потім анімувати елементи швидким рухом. Для анімації використовуємо JavaScript-бібліотеку Anime.js.


Увага! Ми використали найновіші властивості CSS3, тому наші демо не працюватимуть у старих браузерах.


HTML-розмітка для кожного елемента буде однаковою:

<div class="grid grid--effect-vega">
<a href="#" class="grid__item grid__item--c1">
<div class="stack">
<div class="stack__deco"></div>
<div class="stack__deco"></div>
<div class="stack__deco"></div>
<div class="stack__deco"></div>
<div class="stack__figure">
<img class="stack__img" src="img/1.png" alt="Image"/>
</div>
</div>
<div class="grid__item-caption">
<h3 class="grid__item-title">anaerobic</h3>
<div class="column column--left">
<span class="column__text">Period</span>
<span class="column__text">Subjects</span>
<span class="column__text">Result</span>
</div>
<div class="column column--right">
<span class="column__text">2045</span>
<span class="column__text">133456</span>
<span class="column__text">Positive</span>
</div>
</div>
</a>
<a href="#" class="grid__item grid__item--c2"><!-- ... --></a>
<a href="#" class="grid__item grid__item--c2"><!-- ... --></a>
</div><!-- /grid -->

Як видно з коду вище, ми використовуємо певний клас сітки для створення індивідуальних ефектів. Чотири елементи з класом stack_deco — декоративні, ми анімуємо їх разом із stack__figure та зображенням. Сама сітка — це контейнер, який має перспективу. Заголовок сітки містить title і два стовпці, які теж можна анімувати.

Для сітки використовуємо розкладку flexbox. Для кожного елемента в демо застосуємо такі стилі:

.stack {
position: relative;
width: 100%;
height: 200px;
transform-style: preserve-3d;
}
.stack__deco {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: currentColor;
transform-origin: 50% 100%;
}
.stack__deco:first-child {
opacity: 0.2;
}
.stack__deco:nth-child(2) {
opacity: 0.4;
}
.stack__deco:nth-child(3) {
opacity: 0.6;
}
.stack__deco:nth-child(4) {
opacity: 0.8;
}
.stack__figure {
position: relative;
display: flex;
justify-content: center;
align-items: center;
overflow: hidden;
width: 100%;
height: 100%;
cursor: pointer;
transform-origin: 50% 100%;
}
.stack__img {
position: relative;
display: block;
flex: none;
}


Для окремих ефектів задамо спеціальні CSS-стилі:

/* Individual effects */
/* Vega */
.grid--effect-vega .column {
opacity: 1;
}
/* deneb */
.grid--effect-deneb {
perspective: none;
}
.grid--effect-deneb .stack__figure,
.grid--effect-deneb .stack__deco {
transform-origin: 50% 50%;
}
.grid--effect-deneb .column {
opacity: 1;
}
/* ... */

А цей фрагмент JavaScript використовує бібліотеку Anime.js і відповідає за активацію ефектів — при наведенні та навпаки:

HamalFx.prototype._in = function() {
var self = this;

this.DOM.stackItems.map(function(e, i) {
e.style.opacity = i !== self.totalItems - 1 ? 0.2*i+0.2 : 1
});

anime({
targets: this.DOM.stackItems,
duration: 1000,
easing: 'easeOutExpo',
translateY: function(target, index) {
return -1*index*5;
},
rotate: function(target, index, cnt) {
if( index === cnt - 1 ) {
return 0;
}
else {
return index%2 ? (cnt-index)*1 : -1*(cnt-index)*1;
}
},
scale: function(target, index, cnt) {
if( index === cnt - 1 ) {
return 1;
}
else {
return 1.05;
}
},
delay: function(target, index, cnt) {
return (cnt-index-1)*30
}
});

anime({
targets: this.DOM.img,
duration: 1000,
easing: 'easeOutExpo',
scale: 0.7
});

anime({
targets: [this.DOM.columns.left, this.DOM.columns.right],
duration: 1000,
easing: 'easeOutExpo',
translateX: function(target, index) {
return index === 0 ? -30 : 30;
}
});

};

HamalFx.prototype._out = function() {
var self = this;

anime({
targets: this.DOM.stackItems,
duration: 500,
easing: 'easeOutExpo',
translateY: 0,
rotate: 0,
scale: 1,
opacity: function(target, index, cnt) {
return index !== cnt - 1 ? 0 : 1
}
});

anime({
targets: this.DOM.img,
duration: 1000,
easing: 'easeOutElastic',
scale: 1
});

anime({
targets: [this.DOM.columns.left, this.DOM.columns.right],
duration: 500,
easing: 'easeOutExpo',
translateX: 0
});
};


Сподіваємося, ефекти вам сподобалися, а стаття була корисною. Якщо потрібна анімація такого рівня на вашому проєкті — подивіться наші послуги або просто напишіть нам.


Оригінальна стаття доступна за посиланням.
Цікавлять наші послуги?
Залиште заявку!
Відправляючи форму, Ви даєте згоду на обробку персональних даних. Ми гарантуємо що ваші дані
ніколи не будуть передані третім особам.
Відправляємо...
Telegram
Написати в Telegram Відповімо за 5 хвилин