ScrollMagic

ScrollMagic

ScrollMagic е една от алтернативите на Scrollr. Сама по себе си библиотеката позволява да фиксираме елемент на екрана при scroll. В комбинация с GSAP обаче става мощно средство за постигане на parallax ефекти.

Можете да изтеглите библиотеката от http://scrollmagic.io/. А в този урок ще разгледаме няколко елементарни примера как да я използваме.

HTML

Преди да започнем със самите паралакс ефекти, нека първо създадем една семпла страница. Нека в нея включим едно лого, което ще анимираме:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8" />
	<title>Parallax ScrollMagic</title>
</head>
<body>
	<span id="logo">M</span>
</body>
</html>

CSS

Нека добавим basic reset CSS:

* { margin: 0; padding: 0; }

html, body { width: 100%; height: 360vh; } /* 360vh за да имаме поле за scroll и parallax */
body { background: #E0E0E0; color: #333; font: normal 14px/1.35 Arial, Helvetica, sans-seerif; }

Нека зададем следните стилове на логото, за да прилича и то на нещо:

#logo {
	background: #2060DF; /* син фон */
	color: #FFF; /* бял текст */
	font: normal 192px/1.13 Verdana, Arial, sans-serif; /* голям font-size и font-family, което ни харесва; особения line-height е за да държим текста вертикално центриран според фона */
	display: inline-block; /* за да можем да зададем фиксирани елементи на span елемент */
	width: 1.2em; /* еднакви широчина и височина, които са базирани на шрифта; така става красиво квадратче */
	height: 1.2em;
	text-align: center; /* за да излиза текста хоризонтално центриран */
	user-select: none; /* за да се държи повече като картинка и да не може буквата вътре да се селектира */
	position: absolute; /* да го позиционираме на празния екран */
	top: 100vh; /* да е на дъното, за да подтикне хората да scroll-нат и да видят повече */
	left: 50vw; /* да е хоризонтално центрирано */
	transform: translate(-50%, -50%); /* да компенсира размерите на елемента, вместо горния-ляв ъгъл да е в центъра на екрана */
}

JavaScript

И сега вече идва ред на JavaScript-а.

Нека първо заредим всичко, което ще ни трябва:

  • TweenLite.min.js – може и TweenMax.min.js, но нека зареждаме само наистина каквото ни трябва
  • CSSPlugin.min.js – това ще ни трябва, за да анимираме стилове
  • EasePack.min.js – по принцип можем без това, но някои анимации стават по-естествени когато имаме easing
  • ScrollMagic.min.js – все пак пишем урок за него
  • animation.gsap.min.js – интеграция между ScrollMagic и TweenLite/TweenMax; без това „лепило“ между двете, страницата ще доведе до грешки
<script src="TweenLite.min.js"></script>
<script src="CSSPlugin.min.js"></script>
<script src="EasePack.min.js"></script>
<script src="ScrollMagic.min.js"></script>
<script src="animation.gsap.min.js"></script>

А сега вече идва и реда на нашия програмен код, който ще задвижи елементите:

Controller

const controller = new ScrollMagic.Controller();

Вътрешният начин на работа на ScrollMagic изисква да имаме един контролер, който е пряко свързан към scroll bar-а на страницата.

Възможно е при елементи с вътрешен scroll да ви се наложи да регистрирате 2 контролера, но не се сещам за практическа причина за подобно нещо.

Scene

След това нека добавим възможно най-елементарното нещо, което ScrollMagic може:

const scenePin = new ScrollMagic.Scene({ triggerElement: '#logo' })
	.setPin('#logo')
	.addTo(controller);

Да започнем с концепцията за сцени. Всяка една сцена в ScrollMagic трябва да бъде асоциирана с контролер, който да я задвижи.

Една сцена е редно да съдържа една промяна по стилове (примерно да направи елемент фиксиран на екрана, или да добави клас, или пък да го обвърже с промяна на други стилови параметри и т.н.).

Първият аргумент, който подаваме на конструктора е обект с настройки на сцената. Тези настройки включват:

  • triggerElement – може да бъде string с CSS селектор до елемента, за който трябва анимацията да се отнася или направо DOM елемент
  • triggerHook – може да е число от 0 до 1. Има и три стойности, които могат да се представят като string:
    • onEnter или просто 1 (100% разстояние от горния край на екрана) – обозначава, че ScrollMagic ще си свърши работата когато елементът е най-долу на екрана (влиза във viewport-а при scroll)
    • onCenter или 0.5 (50% от viewport-а) – анимацията ще се изпълни, когато елементът попадне в центъра на екрана. Това е и стойността по подразбиране, която ще се използва, ако не зададете друго
    • onLeave или 0 – когато елементът е най-горе и след още малко scroll вече ще излезе от viewport-а.
  • offset – по подразбиране е 0; иначе може да се използва вместо triggerHook или в комбинация с него, за да изместите началото на сцената нагоре или надолу по екрана с фиксирана стойност в пиксели (вместо в проценти, както идва от triggerHook)
  • duration – „продължителност“ на анимацията. Или с други думи – при scroll на още колко пиксела надолу трябва сцената да приключи
  • reverse – дали при scroll в обратна посока сцената също да се изпълни наобратно. По подрадбиране е true
  • loglevel – свързано е с debug-ване. Ако ви трябват повече детайли най-добре се обърнете към официалната документация на http://scrollmagic.io/docs/ScrollMagic.Scene.html#constructor

setPin

След като вече имаме сцена е редно да обвържем някакво действие с нея. Казахме, че ще започнем с най-елементарното, което е просто да фиксираме елемента на екрана. Позицията му се сменя с fixed и той повече не мърда. Така де – защото не сме задали duration. В противен случай щеше да се фиксира само за определено количество scroll, след което пак щеше да си излезе нагоре от екрана, ако продължим да scroll-ваме.

addTo

Накрая с метода addTo на сцената я добавяме към контролера, който сме регистрирали по-рано.

Интеграция с GSAP

Интересната част идва, когато обвържем ScrollMagic с анимации дефинирани с GSAP.

По принцип можем просто при достигане на triggerElement-а до triggerHook-а да изпълним някоя анимация, която сме дефинирали с GSAP. Това обаче не е най-интересното, което можем да направим.

По-забавно би било, ако можем да използваме scroll-а на страницата като инструмент за превъртане на GSAP анимация. Така че като спрем да scroll-ваме, анимацията също да спре. Когато тръгнем да scroll-ваме наобратно – анимацията да се reverse-не. Ако scroll-ваме бавно или бързо – анимацията да се изпълнява със съответна скорост. Това вече може да доведе до parallax.

От квадрат към кръг

Нека след като вече логото е pin-нато в средата на екрана започнем нова сцена:

const vh = window.screen.availHeight / 100;

const sceneCircle = new ScrollMagic.Scene({ triggerElement: '#logo', duration: 50 * vh, offset: 10 * vh })

Константата vh си я регистрирам като помощник за изчисляване на това колко пиксела съответстват на 1vh в CSS.

В случая няма да си даваме зор да преизчисляваме при resize на екрана, но ако разработвате нещо в реални условия би било добре да си напишете кода така, че при промяна на размера на прозореца на браузъра, JavaScript-а да не се счупи.

Като продължителност на сцената задаваме 50vh (50 * vh), като искаме да я изместим и леко надолу от средата на екрана (10vh след като вече елементът е pin-нат).

setTween

След това идва ред на setTween метода на сцената. Точно за тук ни е нужен animation.gsap.min.js, иначе ще имаме JS грешка и GSAP анимацията няма да се обвърже правилно със scroll-а на страницата.

.setTween(new TweenLite.to('#logo', 1, { className: '+=circle' }))

Като параметър на setTween подаваме нов TweenLite (може и TweenMax).

Последния го обвързваме към #logo. Задаваме продължителност 1 секунда, която реално няма да има значение, тъй като анимацията ще е обвързана със scroll-а. Накрая като настройки обаче не подаваме конкретни стилове, а указваме на GSAP да добави клас circle.

Реално не се задава този клас, а посредством CSSPlugin.min.js, GSAP проверява какви стилове ще има елементът при прилагане на този клас и за продължителността на анимацията пресмята средни стойности на стиловете отпреди назначаване на класа, до крайната стойност.

Нека добавим следния CSS стил:

.circle { border-radius: 50%; }

Накрая нека добавим сцената към контролера, който имаме с addTo(controller).

Търкул-търкул

След като логото вече е кръгло, нека добавим и трета сцена, която да го завърти:

const sceneBarrelRoll = new ScrollMagic.Scene({ triggerElement: '#logo', duration: 100 * vh, offset: 75 * vh })
	.setTween(new TweenLite.to('#logo', 1, { rotation: 360, ease: Power1.easeInOut }))
	.addTo(controller);

triggerElement-ът отново е #logo. Продължителността е scroll на един цял екран. offset-ът е изчислен на базата на предходните анимации, така че да се изпълни след като логото вече е станало на кръг.

Чрез setTween задаваме завъртане на 360 градуса, на което задаваме easeInOut от първа степен. Ако минем без този easing можем и да не зареждаме EasePack.min.js, описан по-горе.

Пример

Резултатът от нашите анимации можете да видите на https://magadanski.com/demo/parallax-scrollmagic/.

Вашият коментар

Вашият имейл адрес няма да бъде публикуван. Задължителните полета са отбелязани с *

Този сайт използва Akismet за намаляване на спама. Научете как се обработват данните ви за коментари.